Code of the Day
BeginnerCollision and Polish

Collision concepts

Collision detection asks whether two objects overlap. Axis-aligned bounding boxes are the fast, practical answer for most 2D games.

Game DevBeginner6 min read
Recommended first
By the end of this lesson you will be able to:
  • 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.bottom

If 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.

Finished reading? Mark it complete to track your progress.

On this page