r-type  0.0.0
R-Type main
Loading...
Searching...
No Matches
CollisionSystem.hpp
Go to the documentation of this file.
1///
2/// @file CollisionSystem.hpp
3/// @brief Server-side collision detection and resolution system for R-Type
4/// @details This file contains the collision detection system that runs on the game server.
5/// It handles all collision detection between different entity types (players, enemies,
6/// projectiles, powerups) and applies appropriate responses (damage, destruction, etc.).
7/// The system uses circular collision detection for efficiency and accuracy.
8/// @namespace gme
9/// @author R-Type Team
10/// @date 2025
11///
12
13#pragma once
14
15#include "ECS/Component.hpp"
16#include "ECS/Entity.hpp"
18#include "ECS/Registry.hpp"
20#include <cmath>
21#include <vector>
22
23namespace gme
24{
25 ///
26 /// @struct CollisionPair
27 /// @brief Data structure for storing collision information between two entities
28 /// @details Used to track collisions that have been detected, including the entities
29 /// involved and the degree of overlap for potential resolution.
30 ///
32 {
33 std::uint32_t entityId1; ///< First entity ID in collision
34 std::uint32_t entityId2; ///< Second entity ID in collision
35 float overlapDistance; ///< Distance of overlap (radiusSum - distance)
36 };
37
38 ///
39 /// @class CollisionSystem
40 /// @brief Server-authoritative collision detection and response system
41 /// @details This ECS system manages all collision detection and resolution on the server.
42 /// It performs the following operations each frame:
43 /// - Detects collisions between player projectiles and enemies
44 /// - Detects collisions between enemy projectiles and players
45 /// - Detects collisions between players and enemies (ramming)
46 /// - Detects collisions between players and powerups
47 /// - Applies damage to entities based on collision type
48 /// - Destroys entities when appropriate
49 /// - Tracks collision statistics for debugging
50 ///
51 /// The system uses circular collision detection (radius-based) which is computationally
52 /// efficient for the types of entities in R-Type. All collision resolution is handled
53 /// server-side to maintain authoritative game state.
54 ///
55 /// @namespace gme
56 ///
57 class CollisionSystem final : public ecs::ASystem
58 {
59 public:
60 ///
61 /// @brief Constructor
62 /// @param registry ECS registry containing all entities and components
63 /// @param entityManager Entity manager for spawning/destroying entities
64 /// @details Initializes the collision system with references to required managers
65 ///
66 explicit CollisionSystem(ecs::Registry &registry, EntityManager &entityManager)
67 : m_registry(registry), m_entityManager(entityManager)
68 {
69 }
70
71 ///
72 /// @brief Destructor
73 ///
74 ~CollisionSystem() override = default;
75
76 /// @brief Deleted copy constructor (non-copyable)
78 /// @brief Deleted copy assignment operator (non-copyable)
80 /// @brief Deleted move constructor (non-movable)
82 /// @brief Deleted move assignment operator (non-movable)
84
85 ///
86 /// @brief Update the collision system (called each frame)
87 /// @param registry ECS registry containing all entities
88 /// @param deltaTime Time elapsed since last frame (unused)
89 /// @details Checks for collisions between all relevant entity pairs and applies
90 /// appropriate responses (damage, destruction, etc.)
91 ///
92 void update(ecs::Registry &registry, float deltaTime) override;
93
94 ///
95 /// @brief Get the number of collisions detected this frame
96 /// @return Total collision count
97 /// @details Useful for debugging and performance monitoring
98 ///
99 size_t getCollisionCount() const { return m_collisionCount; }
100
101 ///
102 /// @brief Reset the collision counter to zero
103 /// @details Should be called periodically to prevent overflow
104 ///
106
107 private:
108 ecs::Registry &m_registry; ///< ECS registry reference
109 EntityManager &m_entityManager; ///< Entity manager reference for spawning/destruction
110 size_t m_collisionCount = 0; ///< Counter for collisions detected this frame
111
112 ///
113 /// @brief Check for circular collision between two entities
114 /// @param x1 X position of first entity center
115 /// @param y1 Y position of first entity center
116 /// @param r1 Radius of first entity
117 /// @param x2 X position of second entity center
118 /// @param y2 Y position of second entity center
119 /// @param r2 Radius of second entity
120 /// @param overlapDist Optional output parameter for overlap distance
121 /// @return True if entities are colliding
122 /// @details Uses distance formula: sqrt((x2-x1)² + (y2-y1)²) < (r1 + r2)
123 ///
124 bool checkCircleCollision(float x1, float y1, float r1, float x2, float y2, float r2,
125 float *overlapDist = nullptr) const;
126
127 ///
128 /// @brief Handle collisions between player projectiles and enemies
129 /// @details Iterates through all player projectiles and enemies, checks for collisions,
130 /// applies damage to enemies, and destroys projectiles on hit
131 ///
133
134 ///
135 /// @brief Handle collisions between enemy projectiles and players
136 /// @details Iterates through all enemy projectiles and players, checks for collisions,
137 /// applies damage to players, and destroys projectiles on hit
138 ///
140
141 ///
142 /// @brief Handle collisions between players and enemies (ramming)
143 /// @details Checks for direct collisions between players and enemies,
144 /// applies damage to both entities on contact
145 ///
147
148 ///
149 /// @brief Handle collisions between players and powerups
150 /// @details Checks for collisions between players and powerup items,
151 /// applies powerup effects and destroys the powerup entity
152 ///
154
155 ///
156 /// @brief Extract collision information from an entity
157 /// @param entity Entity to get collision info from
158 /// @param x Output: X position of collision center
159 /// @param y Output: Y position of collision center
160 /// @param radius Output: Collision radius
161 /// @return True if entity has valid Transform and Hitbox components
162 /// @details Calculates collision center from transform position and hitbox offset
163 ///
164 bool getCollisionInfo(ecs::Entity entity, float &x, float &y, float &radius) const;
165
166 ///
167 /// @brief Apply damage to an enemy entity
168 /// @param enemyId Network ID of the enemy entity
169 /// @param damage Amount of damage to apply
170 /// @param attackerPlayerId Session ID of player who dealt damage (for score attribution)
171 /// @details Reduces enemy health and destroys entity if health reaches zero.
172 /// Awards score to attacker if enemy is destroyed.
173 ///
174 void applyDamageToEnemy(std::uint32_t enemyId, float damage, std::uint32_t attackerPlayerId = 0);
175
176 ///
177 /// @brief Apply damage to a player entity
178 /// @param playerId Session ID of the player
179 /// @param damage Amount of damage to apply
180 /// @details Reduces player health. Player death is handled separately.
181 ///
182 void applyDamageToPlayer(std::uint32_t playerId, float damage);
183 };
184
185 ///
186 /// @brief Inline implementation of circular collision detection
187 /// @param x1 X position of first circle center
188 /// @param y1 Y position of first circle center
189 /// @param r1 Radius of first circle
190 /// @param x2 X position of second circle center
191 /// @param y2 Y position of second circle center
192 /// @param r2 Radius of second circle
193 /// @param overlapDist Optional pointer to store overlap distance (radiusSum - actualDistance)
194 /// @return True if circles are overlapping (distance < radiusSum)
195 /// @details Calculates Euclidean distance between centers and compares to sum of radii.
196 /// More efficient than AABB for circular entities.
197 ///
198 inline bool CollisionSystem::checkCircleCollision(float x1, float y1, float r1, float x2, float y2, float r2,
199 float *overlapDist) const
200 {
201 float dx = x2 - x1;
202 float dy = y2 - y1;
203 float distance = std::sqrt(dx * dx + dy * dy);
204 float radiusSum = r1 + r2;
205
206 if (overlapDist)
207 {
208 *overlapDist = radiusSum - distance;
209 }
210
211 return distance < radiusSum;
212 }
213
214 ///
215 /// @brief Inline implementation of collision info extraction
216 /// @param entity Entity to extract collision info from
217 /// @param x Output parameter for collision center X position
218 /// @param y Output parameter for collision center Y position
219 /// @param radius Output parameter for collision radius
220 /// @return True if entity has both Transform and Hitbox components, false otherwise
221 /// @details Combines transform position with hitbox offset to calculate actual collision center
222 ///
223 inline bool CollisionSystem::getCollisionInfo(ecs::Entity entity, float &x, float &y, float &radius) const
224 {
225 auto *transform = m_registry.getComponent<ecs::Transform>(entity);
226 auto *hitbox = m_registry.getComponent<ecs::Hitbox>(entity);
227
228 if (!transform || !hitbox)
229 return false;
230
231 x = transform->x + hitbox->offsetX;
232 y = transform->y + hitbox->offsetY;
233 radius = hitbox->radius;
234 return true;
235 }
236
237} // namespace gme
This file contains the component definitions.
Centralized entity lifecycle management system for R-Type server.
This file contains the entity definitions.
This file contains the interface for systems.
This file contains the Registry class declaration.
Abstract class for system.
Definition ISystems.hpp:34
Class for managing entities and their components.
Definition Registry.hpp:25
T * getComponent(Entity e)
Definition Registry.hpp:71
Server-authoritative collision detection and response system.
CollisionSystem(CollisionSystem &&)=delete
Deleted move constructor (non-movable)
bool getCollisionInfo(ecs::Entity entity, float &x, float &y, float &radius) const
Extract collision information from an entity.
size_t getCollisionCount() const
Get the number of collisions detected this frame.
void resetCollisionCount()
Reset the collision counter to zero.
~CollisionSystem() override=default
Destructor.
void handlePlayerPowerupCollision()
Handle collisions between players and powerups.
bool checkCircleCollision(float x1, float y1, float r1, float x2, float y2, float r2, float *overlapDist=nullptr) const
Check for circular collision between two entities.
size_t m_collisionCount
Counter for collisions detected this frame.
void handlePlayerProjectileEnemyCollision()
Handle collisions between player projectiles and enemies.
CollisionSystem & operator=(CollisionSystem &&)=delete
Deleted move assignment operator (non-movable)
void applyDamageToEnemy(std::uint32_t enemyId, float damage, std::uint32_t attackerPlayerId=0)
Apply damage to an enemy entity.
CollisionSystem(ecs::Registry &registry, EntityManager &entityManager)
Constructor.
ecs::Registry & m_registry
ECS registry reference.
void applyDamageToPlayer(std::uint32_t playerId, float damage)
Apply damage to a player entity.
void update(ecs::Registry &registry, float deltaTime) override
Update the collision system (called each frame)
CollisionSystem & operator=(const CollisionSystem &)=delete
Deleted copy assignment operator (non-copyable)
CollisionSystem(const CollisionSystem &)=delete
Deleted copy constructor (non-copyable)
void handleEnemyProjectilePlayerCollision()
Handle collisions between enemy projectiles and players.
EntityManager & m_entityManager
Entity manager reference for spawning/destruction.
void handlePlayerEnemyCollision()
Handle collisions between players and enemies (ramming)
Central entity lifecycle manager for the R-Type game server.
std::uint32_t Entity
Definition Entity.hpp:13
Data structure for storing collision information between two entities.
std::uint32_t entityId1
First entity ID in collision.
std::uint32_t entityId2
Second entity ID in collision.
float overlapDistance
Distance of overlap (radiusSum - distance)