Skip to content

CollisionSystem

Manages collision detection between entities.

Description

CollisionSystem iterates through registered entities, checks if they are Actors, and performs AABB (Axis-Aligned Bounding Box) collision checks based on their collision layers and masks.

The system automatically filters collisions using layers and masks, avoiding unnecessary checks. When a collision is detected, it triggers the onCollision() callback on both actors.

Namespace

namespace pixelroot32::physics {
    class CollisionSystem {
        // ...
    };
}

Inheritance

  • Base class: None (standalone class)
  • Used by: Scene (manages collision system instance)

Public Methods

void addEntity(Entity* e)

Adds an entity to the collision system.

Parameters: - e (pixelroot32::core::Entity*): Pointer to the entity to add

Returns: - void

Notes: - Only Actor entities participate in collisions - Entities are automatically added when added to Scene - Typically not called directly (handled by Scene)

Example:

// Typically handled automatically by Scene
scene->addEntity(actor);  // Automatically added to collision system

void removeEntity(Entity* e)

Removes an entity from the collision system.

Parameters: - e (pixelroot32::core::Entity*): Pointer to the entity to remove

Returns: - void

Notes: - Entities are automatically removed when removed from Scene - Typically not called directly

Example:

// Typically handled automatically by Scene
scene->removeEntity(actor);  // Automatically removed from collision system

void update()

Performs collision detection for all registered entities.

Returns: - void

Notes: - Called automatically by Scene::update() - Iterates through all pairs of entities - Only checks collisions between Actors with matching layers/masks - Triggers onCollision() callbacks when collisions are detected - Uses AABB (Axis-Aligned Bounding Box) collision detection

Example:

// Called automatically by Scene, but can be called manually:
void update(unsigned long deltaTime) override {
    Scene::update(deltaTime);  // Calls collisionSystem.update()

    // Or manually:
    collisionSystem.update();
}

How It Works

  1. Entity Registration: Entities added to Scene are automatically registered
  2. Layer Filtering: Only actors with matching layers/masks are checked
  3. AABB Check: Uses Rect::intersects() for collision detection
  4. Callback: Calls onCollision() on both actors when collision detected

Collision Detection Algorithm

for each actor1 in entities:
    if actor1 is not an Actor: continue
    for each actor2 in entities:
        if actor2 is not an Actor: continue
        if actor1 == actor2: continue

        // Check layers/masks
        if (actor1->layer & actor2->mask) == 0: continue
        if (actor2->layer & actor1->mask) == 0: continue

        // Check AABB intersection
        Rect box1 = actor1->getHitBox();
        Rect box2 = actor2->getHitBox();

        if (box1.intersects(box2)) {
            actor1->onCollision(actor2);
            actor2->onCollision(actor1);
        }

Usage Example

#include "physics/CollisionSystem.h"
#include "core/Actor.h"

class GameScene : public pixelroot32::core::Scene {
public:
    void init() override {
        // Create actors with collision layers
        PlayerActor* player = new PlayerActor(64, 64);
        player->layer = pixelroot32::physics::DefaultLayers::kPlayer;
        player->mask = pixelroot32::physics::DefaultLayers::kEnemy | 
                       pixelroot32::physics::DefaultLayers::kObstacle;
        addEntity(player);

        EnemyActor* enemy = new EnemyActor(100, 100);
        enemy->layer = pixelroot32::physics::DefaultLayers::kEnemy;
        enemy->mask = pixelroot32::physics::DefaultLayers::kPlayer;
        addEntity(enemy);

        // Collision system is managed by Scene
        // Collisions are checked automatically in Scene::update()
    }

    void update(unsigned long deltaTime) override {
        // Collision detection happens here automatically
        Scene::update(deltaTime);
    }
};

Performance Considerations

  • Layer filtering: Very efficient; avoids most collision checks
  • AABB checks: Fast (simple rectangle intersection)
  • Pair checking: O(n²) complexity, but n is limited (MAX_ENTITIES = 32)
  • Update frequency: Called every frame; keep hitboxes simple

ESP32 Considerations

  • Entity limit: MAX_ENTITIES = 32 limits collision pairs
  • Layer efficiency: Use layers effectively to minimize checks
  • Hitbox simplicity: Keep hitboxes as simple AABB for best performance

See Also