Skip to content

Collision Manager

Central collision detection system implementing multiple collision algorithms for precise vehicle and object interactions in a racing game.


🎯 Core Responsibilities

FunctionAlgorithmUse Case
Vehicle-Track CollisionGrid-basedOff-track detection
Object-Object CollisionSAT (Separating Axis Theorem)Precise hitbox detection
RaycastingLine intersectionAI vision/sensors
Path IntersectionDistance-basedRoute planning

🏗️ Constructor

constructor(scalingFactor: number)
ParameterTypeDescription
scalingFactornumberGrid resolution for track collider

Singleton Pattern:

  • Accessed via CollisionManager.instance
  • Ensures single collision system instance

📊 Properties

PropertyTypeDescription
scalingFactornumberTrack collider grid resolution
_instanceCollisionManager | nullSingleton instance reference

🛠️ Core Methods

Collision Detection

isCollidingWithTrack()

public isCollidingWithTrack(corners: Vec2D[], trackCollider: number[][]): Vec2D | null

Grid-based track boundary detection:

  1. Converts world to grid coordinates
  2. Checks all vehicle corners
  3. Returns first collision point

isCollidingWithAnotherObject()

public isCollidingWithAnotherObject(object1: CollisionObject | Vec2D[], object2: CollisionObject): boolean

SAT implementation for precise hitbox detection:

  1. Gets rotated corners
  2. Calculates separation axes
  3. Projects shapes
  4. Checks overlaps

Raycasting

rayCastFromController()

rayCastFromController(
controller: PhysicsBasedController,
length: number,
angleOffset: number,
debug: boolean = false
): Vec2D | null

Casts ray from vehicle:

  • Checks opponents and obstacles
  • Returns closest intersection
  • Optional debug visualization

Path Analysis

getActualPathIntersections()

getActualPathIntersections(
actualPath: CheckPoint[],
sampledPoints: CheckPoint[],
controllerToSkip: OpponentController
)

Finds obstacles along AI path:

  • Uses SOME_ARBITRARY_THRESHOLD (100 units)
  • Returns intersection segments

⚙️ Supporting Methods

Geometry Utilities

MethodDescription
getRotatedCorners()Calculates oriented bounding box
getAxes()Gets separation axes for SAT
projectPolygon()Projects shape onto axis
overlaps()Checks projection overlap

Spatial Query

MethodDescription
getGridPosition()World-to-grid conversion
circleOverlapsWithTrack()Circular area check

🧠 Algorithm Details

Separating Axis Theorem (SAT)

graph TD
A[Get Rotated Corners] --> B[Calculate Axes]
B --> C[Project Shapes]
C --> D[Check Overlaps]
D --> E{All Axes Overlap?}
E -->|Yes| F[Collision]
E -->|No| G[No Collision]

Track Collision Grid

  • 2D array representing drivable areas
  • 0 = drivable, 1 = collision
  • Scaled by scalingFactor

🏎️ Usage Examples

Basic Collision Check

const corners = getCarCorners(position, width, height, angle);
const collisionPoint = collisionManager.isCollidingWithTrack(corners, trackCollider);

Object Collision

if (collisionManager.isCollidingWithAnotherObject(car1, car2)) {
physicsDriver.handleCollision(car1, car2);
}

AI Raycasting

const obstacle = collisionManager.rayCastFromController(aiCar, 200, 0, true);

⚠️ Edge Cases

  1. Undefined Objects:

    • Skipped in raycasting/path checks
    • Commented frustration about array pollution :)
  2. Grid Boundaries:

    • Explicit bounds checking
    • Returns collision for out-of-bounds
  3. Boost Perks:

    • Specifically excluded from path checks

🛠️ Performance Considerations

  1. Grid Resolution:

    • Higher scalingFactor = coarser checks
    • Balance precision vs performance
  2. SAT Optimization:

    • Early exit on first separating axis
    • Cached axes where possible
  3. Raycasting:

    • Limited to essential objects
    • Debug mode adds overhead

📈 Extension Points

  1. Spatial Partitioning:

    • Add quadtree for opponent checks
  2. Collision Layers:

    • Implement category filtering
  3. Damage Zones:

    • Extend track collider values