Almost everything that makes a video game interesting depends on knowing when two things touch. Today we formalize that question with simple math and reusable code.
In the previous lesson we handled sprite animation. Before that, in Pong, we used `SDL_HasIntersection` to detect when the ball touched a paddle — a quick but limited solution. In this lesson we'll understand what that function does internally, and we'll build collision detection that works for both rectangles and circles, because not every game uses only boxes.
Collision detection is the foundation of: combat damage, item pickups, hits from projectiles, characters that can't walk through walls, and practically any physical interaction in a 2D game.
AABB stands for "Axis-Aligned Bounding Box" — a box aligned to the axes, meaning no rotation. It's the cheapest collision shape to compute and the most common one in 2D games.
The logic is simple: two rectangles do NOT overlap if one is entirely to the left, right, above, or below the other. If none of those four conditions is true, they're touching.
This is exactly what `SDL_HasIntersection` does internally. Now that you understand it, you can extend it — for example, computing how much overlap there is (to resolve the collision by pushing the objects apart) instead of just knowing whether they collide.
For round objects (a ball, an explosion, a projectile), circle collision is more precise and, surprisingly, simpler to compute: two circles collide if the distance between their centers is less than the sum of their radii.
Notice the performance trick: we compare the squared distance against the squared sum of the radii instead of using `sqrt()`. Square root is a relatively expensive operation, and here it's completely avoidable — we only care whether one distance is greater or smaller than another, not its exact value.
A very common mixed case: a round ball against a rectangular platform. The standard technique is to find the point on the rectangle closest to the circle's center, and measure the distance from there.
Now we can replace the improvised `SDL_HasIntersection` from lesson 3 with our own AABB function, and use the overlap to decide whether the bounce should be horizontal or vertical based on which side the impact happened on.
A frequent bug: if you don't separate the objects after detecting the collision, the same hit gets detected across several consecutive frames and the object "shakes" or gets stuck. The fix is to push the objects out of the overlap zone immediately after resolving the physics.
Collision geometry is an area where AI assistants are particularly good at explaining "why" a formula works, not just "what" it does. If the math behind the closest-point circle-rectangle collision isn't fully clear to you, ask your assistant to draw it out in ASCII or explain it with a concrete numeric case (for example, a circle at `(50, 50)` with radius `10` against a rectangle at `(0,0,40,40)`). Watching the numbers move helps far more than the formula alone.
With collisions solved, in the next lesson we'll use these same data structures (positions, character states) as the foundation for something different: a save system that gives your game persistent memory between sessions.
Carlos Montiel is an enterprise AI solutions architect. He implements LLMs, Agents, RAG, and orchestrators for companies across Guatemala and Latin America. Reach out for a consultation.
Contact Carlos Montiel