Collision Detection
Collision detection answers a question every game asks constantly: are two things touching? The ball and a brick, the player and a wall, a bullet and an enemy. The maths is simpler than it sounds for the common cases, and getting it right is what makes a game feel solid rather than ghostly. This article covers rectangle and circle collisions, how to respond to a hit, and how to keep checks fast as objects multiply.
The Breakout demo uses rectangle checks for every brick, and Pong for its paddles.
What you'll learn
What collision detection is
At heart it is a test for whether two shapes share any space.
Overlap, then react
Collision detection is checking, each frame, whether two objects overlap, and collision response is what the game does about it, bouncing, stopping, or removing something. The two steps are distinct: first you detect, then you respond. Most games approximate objects as simple shapes, rectangles and circles, because exact shape tests are far more expensive and rarely needed.
Rectangle collisions
The workhorse of 2D games is the axis aligned bounding box.
The AABB overlap test
function overlap(a, b) {
return a.x < b.x + b.w &&
a.x + a.w > b.x &&
a.y < b.y + b.h &&
a.y + a.h > b.y;
}
Two rectangles overlap only if they overlap on both the horizontal and vertical axes. The four comparisons above check exactly that. This single function handles the player against walls, the ball against bricks, and most other pairs in a 2D game.
Circle collisions
Round objects are better tested as circles than as boxes.
Distance versus radius
function circlesHit(a, b) {
var dx = a.x - b.x, dy = a.y - b.y;
var distSq = dx * dx + dy * dy;
var r = a.r + b.r;
return distSq < r * r; // compare squared to avoid a square root
}
Two circles touch when the distance between their centres is less than the sum of their radii. Comparing squared distances skips the square root, a small but worthwhile saving when this runs many times a frame.
Responding to a hit
Detecting the overlap is half the job; the game must then react.
Bounce, block, or remove
A response depends on the game. The ball in Breakout reverses its vertical direction and the brick is removed; a player hitting a wall is pushed back out of it. Often you also separate the objects so they are no longer overlapping, preventing them sticking together. The state changes a hit triggers, a destroyed brick or a lost life, are tracked through game state management.
Keeping checks fast
Testing every object against every other becomes slow as numbers grow.
Avoiding wasted tests
Checking all pairs is fine for a few dozen objects but grows quickly with more. Common speedups skip far apart objects with a cheap distance check first, or divide the world into a grid so each object is only tested against neighbours in the same cell. These are worth adding only when a simple all pairs check actually becomes a bottleneck, which the game loop timing will reveal.
Common pitfalls
Collisions have a few well known traps.
What usually goes wrong
The most common is tunnelling, where a fast object passes through a thin wall between frames because it never overlapped on any single frame; a fixed time step or a swept check helps. The second is detecting a hit but forgetting to separate the objects, so they stay overlapped and trigger repeatedly. The third is using a box for a clearly round object, which feels wrong at the corners. The fixed stepping that prevents tunnelling is covered in game loop fundamentals.
Frequently Asked Questions
How does collision detection work in a game?
Each frame the game tests whether two objects overlap, then responds if they do. Most games approximate objects as rectangles or circles, because those overlap tests are cheap and exact shape tests are rarely needed.
How do I check if two rectangles overlap?
Two rectangles overlap only if they overlap on both axes: the left of each is past the right of the other on the horizontal axis, and the same vertically. Four comparisons test exactly that.
How do I detect a collision between two circles?
Two circles touch when the distance between their centres is less than the sum of their radii. Comparing squared distances avoids a square root, which is worthwhile when the check runs many times a frame.
Why does my fast object pass through walls?
That is tunnelling: the object moves so far in one frame that it never overlaps the wall on any single frame. A fixed time step or a swept collision check that tests the path between frames prevents it.
Read next: game state management, or the Game Development hub.