Unit 12.3A · Term 3

Collision Detection

Collision detection is how games know when two objects touch — like a player hitting a coin, a bullet hitting an enemy, or a character bumping into a wall. PyGame uses rectangles to check for these overlaps efficiently.

Learning Objectives

  • 12.5.3.1 Code the movement of graphic objects
  • 12.5.3.6 Process events (collisions)

Lesson Presentation

12.3A-collision-detection.pdf · Slides for classroom use

Conceptual Anchor

The Bounding Box Analogy

Imagine every object in your game is wrapped in an invisible rectangular box. To check if two complex shapes touch, we just check "do their boxes overlap?". It's fast, simple, and works for 99% of 2D games.

Rules & Theory

Rectangle Collisions (Rect vs Rect)

# Check if two Rects overlap if player_rect.colliderect(coin_rect): print("Hit!") # Check if a Rect contains a point (e.g., mouse click) if button_rect.collidepoint(mx, my): print("Clicked!")

Sprite Collisions (Sprite vs Group)

Function Description
pygame.sprite.spritecollide(sprite, group, dokill) Returns a list of sprites from the group that intersect with the sprite.
dokill=True removes hit sprites from the group.
pygame.sprite.groupcollide(grp1, grp2, kill1, kill2) Checks for collisions between two groups. Returns a dictionary of hits.
kill1/kill2 determine if hit sprites are removed.

Worked Examples

1 Collecting Coins (Sprite vs Group)

# Player hits coins -> coins disappear, score increases hits = pygame.sprite.spritecollide(player, coins, True) for coin in hits: # This loop runs once for every coin hit this frame score += 10 play_coin_sound() print("Coin collected!")

2 Bullets Hitting Enemies (Group vs Group)

# Bullets (grp1) hit Enemies (grp2) # True, True -> BOTH bullet and enemy disappear hits = pygame.sprite.groupcollide(bullets, enemies, True, True) for bullet in hits: # hits is a dict: {bullet: [enemy1, enemy2...]} # usually 1 bullet hits 1 enemy for enemy in hits[bullet]: score += 50 create_explosion(enemy.rect.center)

3 Wall Collision (Stop Movement)

# Move x-axis player.rect.x += player.vel_x # Check wall collisions immediately hits = pygame.sprite.spritecollide(player, walls, False) for wall in hits: if player.vel_x > 0: # Moving right; hit left side of wall player.rect.right = wall.rect.left elif player.vel_x < 0: # Moving left; hit right side of wall player.rect.left = wall.rect.right # Move y-axis player.rect.y += player.vel_y # Check wall collisions again hits = pygame.sprite.spritecollide(player, walls, False) for wall in hits: if player.vel_y > 0: # Moving down; hit top of wall player.rect.bottom = wall.rect.top elif player.vel_y < 0: # Moving up; hit bottom of wall player.rect.top = wall.rect.bottom

Common Pitfalls

Tunneling Effect

If an object moves too fast (e.g., speed=50), it might "jump" completely over a thin wall (width=10) in a single frame without ever overlapping it. Fix: limit speed or use multiple smaller steps.

Modifying List While Iterating

spritecollide(..., True) modifies the group internally, which is safe. But if you manually loop through a list and remove items (for enemy in enemies: enemies.remove(enemy)), it can cause errors. Iterate over a copy instead: pixels[:].

Tasks

Apply

Create a game where the player collects randomly placed "food" squares. Score +1 for each.

Apply

Create a "dodge the falling rocks" game. If player collides with a rock, game over.

Create

Implement a maze game where the player cannot walk through wall sprites (use the stop movement logic).

Self-Check Quiz

Q1: What does dokill=True mean in spritecollide?

It means the sprites in the group that are hit will be automatically removed (killed) from the group.

Q2: How do you check if a point is inside a rectangle?

rect.collidepoint(x, y) — useful for mouse clicks on buttons.

Q3: Why separate x and y movement for wall collisions?

To know which side was hit. If you move diagonally and hit a corner, checking x and y separately lets you slide along the wall instead of getting stuck.