-
Notifications
You must be signed in to change notification settings - Fork 1
CollisionHelper
CollisionHelper provides a complete suite of collision detection and resolution functions for 2D games. It handles everything from basic overlap checks to advanced swept collisions that prevent tunneling.
Collision is one of the most common and error-prone parts of game development. CollisionHelper centralizes all collision logic in one place, making it easy to:
- Detect when shapes overlap
- Resolve overlaps by pushing objects apart
- Prevent tunneling with swept collisions
- Raycast for line-of-sight and aiming
- Slide along walls with move-and-slide
All methods use Rect2 and Vect2 - no separate Circle struct is needed.
Check if two rectangles overlap.
if (CollisionHelper.RectRect(player, wall))
{
// Player hit the wall
}Check if two circles overlap.
if (CollisionHelper.CircleCircle(playerPos, 16f, enemyPos, 20f))
{
// Player hit the enemy
}Check if a rectangle and a circle overlap.
if (CollisionHelper.RectCircle(wall, playerPos, 16f))
{
// Player circle hit the wall
}Check if a point is inside a rectangle or circle.
if (CollisionHelper.PointRect(mousePos, buttonRect))
{
// Mouse is over the button
}
if (CollisionHelper.PointCircle(mousePos, explosionCenter, 50f))
{
// Mouse is within explosion radius
}Check if a line segment intersects a rectangle or circle.
if (CollisionHelper.LineRect(start, end, wall))
{
// Line of sight is blocked by wall
}Distance checks are useful for AI and proximity detection without doing full collision tests.
// Distance between two rectangles
float dist = CollisionHelper.DistanceRectRect(player, enemy);
// Distance between two circles
float dist = CollisionHelper.DistanceCircleCircle(playerPos, 16f, enemyPos, 20f);
// Distance between a rectangle and a circle
float dist = CollisionHelper.DistanceRectCircle(wall, playerPos, 16f);
// Check if enemy is within aggro range
if (CollisionHelper.DistanceCircleCircle(playerPos, 16f, enemyPos, 20f) < 100f)
{
// Enemy starts chasing
}Raycasts are useful for line-of-sight, aiming, shooting, and visibility checks.
// Cast a ray from player toward mouse
Vect2 direction = (mousePos - player.Center).Normalized();
if (CollisionHelper.RaycastRect(player.Center, direction, wall, out Vect2 hit, out float distance))
{
// Wall is in the way at 'hit' position
DrawLine(player.Center, hit, Color.Red);
}List<Rect2> walls = new();
List<(Vect2 center, float radius)> enemies = new();
if (CollisionHelper.RaycastAny(origin, direction, walls, enemies,
out Vect2 hit, out Vect2 normal, out float dist, out object hitObject))
{
// Hit something! hitObject tells you what it was
if (hitObject is Rect2) { /* Hit a wall */ }
if (hitObject is Vect2) { /* Hit an enemy */ }
}Swept collision prevents tunneling - when fast-moving objects pass through thin walls in a single frame.
// Fast-moving bullet
Rect2 bullet = new Rect2(100, 100, 4, 4);
Vect2 bulletVelocity = new Vect2(1000, 0);
if (CollisionHelper.SweptRectRect(bullet, bulletVelocity, wall,
out float timeOfImpact, out Vect2 hitPoint, out Vect2 hitNormal))
{
// Bullet will hit the wall at timeOfImpact (0-1)
// Move bullet to hitPoint and bounce/stop
}This works for:
-
SweptRectRect- Rectangle vs rectangle -
SweptCircleRect- Circle vs rectangle -
SweptCircleCircle- Circle vs circle
Normals tell you which direction a collision came from. Useful for bouncing, sliding, and pushing.
// Get the normal between overlapping shapes
Vect2 normal = CollisionHelper.GetCollisionNormal(player, wall);
// normal is (-1, 0) for left, (1, 0) for right, (0, -1) for top, (0, 1) for bottom
// Reflect velocity off the surface
Vect2 reflected = CollisionHelper.Reflect(velocity, normal, 0.8f);
// 80% bouncinessPushback resolves overlaps by pushing objects apart. This is essential for preventing objects from merging into each other.
if (CollisionHelper.RectRect(player, wall))
{
Vect2 push = CollisionHelper.PushRectRect(player, wall);
player.Position += push; // Push player out of the wall
}Pushback methods:
-
PushRectRect- Rect vs rect -
PushCircleRect- Circle vs rect -
PushCircleCircle- Circle vs circle
Move and slide lets you move an object and have it automatically slide along walls instead of stopping dead.
// Move player with slide along walls
Vect2 velocity = new Vect2(5, 0);
List<Rect2> obstacles = new List<Rect2> { wall, floor };
player.Position = CollisionHelper.MoveAndSlideRect(player, velocity, obstacles);Vect2 circlePos = new Vect2(150, 150);
float radius = 16f;
Vect2 velocity = new Vect2(5, 0);
List<Rect2> rectObstacles = new() { wall };
List<(Vect2 center, float radius)> circleObstacles = new()
{
(new Vect2(250, 250), 20f)
};
circlePos = CollisionHelper.MoveAndSlideCircle(
circlePos, radius, velocity, rectObstacles, circleObstacles);Check if one shape fully contains another.
// Is the player fully inside the safe zone?
if (CollisionHelper.RectContainsRect(safeZone, player))
{
// Player is safe!
}
// Is the circle fully inside the rectangle?
if (CollisionHelper.RectContainsCircle(rect, circleCenter, radius))
{
// Circle is fully contained
}Convert a circle to its bounding box (AABB) for broadphase optimization - skip expensive checks when objects are far apart.
// Get the bounding box of a circle
Rect2 circleBounds = CollisionHelper.GetCircleBounds(circlePos, 25f);
// Quick broadphase check
if (CollisionHelper.RectRect(circleBounds, wall))
{
// Now do the precise circle-rect check
if (CollisionHelper.RectCircle(wall, circlePos, 25f))
{
// Actually hit the wall
}
}Find the closest point on a shape to a given point.
// Closest point on a rectangle
Vect2 closest = CollisionHelper.ClosestPointRect(mousePos, buttonRect);
// Closest point on a circle
Vect2 closest = CollisionHelper.ClosestPointCircle(mousePos, explosionCenter, 50f);Bounce a velocity off a surface with optional bounciness.
// Bounce a ball off a wall
Vect2 normal = CollisionHelper.GetCollisionNormal(ball, wall);
ballVelocity = CollisionHelper.Reflect(ballVelocity, normal, 0.9f); // 90% bounce| Category | What It Does |
|---|---|
| Detection | Check if shapes overlap (Rect, Circle, Point, Line) |
| Distance | Measure distance between shapes |
| Raycast | Cast rays against shapes |
| Swept Collision | Prevent tunneling for fast-moving objects |
| Normals | Get collision direction |
| Pushback | Resolve overlaps |
| Move & Slide | Slide along walls |
| Containment | Check if one shape contains another |
| Bounds Conversion | Get AABB for broadphase |
| Closest Point | Find nearest point on a shape |
| Reflection | Bounce velocities off surfaces |
- CollisionHelper
- MathHelper
- FileHelper
- HashHelper
- JsonHelper
- MapHelper
- TextHelper
- SoundHelper
- AlignHelpers
- Instance Helper
- Enum Extensions
- String Extensions
- Int Extensions
- Float Extensions
- IEnumerable Extensions
- Random Extensions
- Sound Extensions
- Font Extensions