Collision concepts
Collision detection asks whether two objects overlap. Axis-aligned bounding boxes are the fast, practical answer for most 2D games.
- Explain what collision detection is and why it matters
- Describe axis-aligned bounding box (AABB) collision
- Understand why AABB is the right starting point for most 2D games
Games are built from objects that interact. A bullet hits an enemy. A player runs into a wall. A collectible is picked up. All of these interactions share the same underlying question: are these two things in the same place right now? That question is collision detection.
If you already used pygame.Rect.colliderect() in the basic game lab, you have
already done collision detection. This lesson explains what is actually happening
inside that method, so you can reason about it when things go wrong.
Axis-aligned bounding boxes
The most common approach to 2D collision detection is the axis-aligned bounding box, or AABB. A bounding box is a rectangle that wraps around an object. "Axis-aligned" means the rectangle's sides are parallel to the screen axes — no rotation.
Two AABB rectangles overlap when they overlap on both the horizontal axis and the vertical axis simultaneously.
Consider two rectangles, A and B:
- A spans x from 100 to 150, y from 80 to 120.
- B spans x from 130 to 180, y from 100 to 140.
On the x axis: A ends at 150 and B starts at 130. 130 < 150, so they overlap horizontally. On the y axis: A ends at 120 and B starts at 100. 100 < 120, so they overlap vertically. Both axes overlap — the rectangles collide.
The general rule: two rectangles A and B do not collide if any of these
are true:
A is entirely left of B: A.right <= B.left
A is entirely right of B: A.left >= B.right
A is entirely above B: A.bottom <= B.top
A is entirely below B: A.top >= B.bottomIf none of those separating conditions hold, the rectangles must overlap. This
is the core of the AABB check, and it is what pygame.Rect.colliderect() runs
under the hood.
Why AABB is the right starting point
AABB has one big limitation: the box does not conform to the shape of the sprite. A diagonal sword blade has a rectangular bounding box, so the collision region is larger than the visible blade. This is sometimes called "hitbox generosity" in game design circles.
For beginner projects — and for many commercial 2D games — that imprecision is fine. The reasons AABB wins:
Speed. The check is six comparisons and two logical AND operations. It runs in constant time regardless of shape complexity. You can check hundreds of pairs per frame without a measurable cost.
Simplicity. Every object in pygame already has a Rect. No extra data to
maintain. colliderect() is one method call.
Good enough. Players are forgiving of slightly generous or slightly tight hitboxes, especially when the frame rate is smooth and the rest of the game feels right. Perfect pixel-level collision is a problem to solve much later, if ever.
When a collision feels wrong — "I didn't touch that!" or "I clearly hit it!" —
the hitbox is almost always the culprit. Draw your rects in a debug mode
(pygame.draw.rect(screen, (255,0,0), rect, 2) draws an outline) to verify
the collision region matches your expectations.
Where to go next
Next: collision in code — using pygame.Rect and .colliderect() to detect
and respond to collisions between the player and obstacles.
Lab: Build a basic game
Apply the game loop, player input, and state management to build a minimal but complete game — a player that moves, a target to reach, and a win condition.
Collision in code
Use pygame.Rect and its colliderect method to detect overlaps between the player and obstacles, then respond to them.