Collision Manager
Central collision detection system implementing multiple collision algorithms for precise vehicle and object interactions in a racing game.
🎯 Core Responsibilities
| Function | Algorithm | Use Case |
|---|---|---|
| Vehicle-Track Collision | Grid-based | Off-track detection |
| Object-Object Collision | SAT (Separating Axis Theorem) | Precise hitbox detection |
| Raycasting | Line intersection | AI vision/sensors |
| Path Intersection | Distance-based | Route planning |
🏗️ Constructor
constructor(scalingFactor: number)| Parameter | Type | Description |
|---|---|---|
scalingFactor | number | Grid resolution for track collider |
Singleton Pattern:
- Accessed via
CollisionManager.instance - Ensures single collision system instance
📊 Properties
| Property | Type | Description |
|---|---|---|
scalingFactor | number | Track collider grid resolution |
_instance | CollisionManager | null | Singleton instance reference |
🛠️ Core Methods
Collision Detection
isCollidingWithTrack()
public isCollidingWithTrack(corners: Vec2D[], trackCollider: number[][]): Vec2D | nullGrid-based track boundary detection:
- Converts world to grid coordinates
- Checks all vehicle corners
- Returns first collision point
isCollidingWithAnotherObject()
public isCollidingWithAnotherObject(object1: CollisionObject | Vec2D[], object2: CollisionObject): booleanSAT implementation for precise hitbox detection:
- Gets rotated corners
- Calculates separation axes
- Projects shapes
- Checks overlaps
Raycasting
rayCastFromController()
rayCastFromController( controller: PhysicsBasedController, length: number, angleOffset: number, debug: boolean = false): Vec2D | nullCasts 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
| Method | Description |
|---|---|
getRotatedCorners() | Calculates oriented bounding box |
getAxes() | Gets separation axes for SAT |
projectPolygon() | Projects shape onto axis |
overlaps() | Checks projection overlap |
Spatial Query
| Method | Description |
|---|---|
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
-
Undefined Objects:
- Skipped in raycasting/path checks
- Commented frustration about array pollution :)
-
Grid Boundaries:
- Explicit bounds checking
- Returns collision for out-of-bounds
-
Boost Perks:
- Specifically excluded from path checks
🛠️ Performance Considerations
-
Grid Resolution:
- Higher
scalingFactor= coarser checks - Balance precision vs performance
- Higher
-
SAT Optimization:
- Early exit on first separating axis
- Cached axes where possible
-
Raycasting:
- Limited to essential objects
- Debug mode adds overhead
📈 Extension Points
-
Spatial Partitioning:
- Add quadtree for opponent checks
-
Collision Layers:
- Implement category filtering
-
Damage Zones:
- Extend track collider values