Menu
CoddyTech

Catch with spritecollide

Part of the Sprites and Images section of Coddy's Pygame journey. Lesson 19 of 36.

Coins rain down, and the ship should catch them. One sprite against a whole group is a single call:

caught = pygame.sprite.spritecollide(player, coins, True)
score += len(caught)

spritecollide(sprite, group, dokill) returns a list of the sprites in the group whose rect overlaps the sprite's rect. The list is empty when nothing touches, so len(caught) is the number caught this frame.

The third argument, dokill, says what happens to the ones that touch. True kills them, the same as calling kill() on each, so a coin is caught once. With False they stay: right for an enemy you only bump into, wrong for a coin, which would add a point every frame it overlaps the ship.

Do the test in the update part of the loop, after the sprites have moved.

challenge icon

Challenge

Medium
  1. After coins.update(), collect the coins touching the player with pygame.sprite.spritecollide, killing them.
  2. Add how many were caught to score. The starter already shows Score: and the score.

Try it yourself

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Coin Catcher")
clock = pygame.time.Clock()

ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
coin_image = pygame.image.load("assets/images/coin.png").convert_alpha()
font = pygame.font.Font(None, 32)


class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = ship_image
        self.rect = self.image.get_rect(midbottom=(320, 470))

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.rect.x -= 6
        if keys[pygame.K_RIGHT]:
            self.rect.x += 6
        self.rect.clamp_ip(screen.get_rect())


class Coin(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = coin_image
        self.rect = self.image.get_rect(center=(random.randint(20, 620), random.randint(-400, -20)))

    def update(self):
        self.rect.y += 2
        if self.rect.top > 480:
            self.rect.center = (random.randint(20, 620), -20)


player = Player()
coins = pygame.sprite.Group()
for i in range(6):
    coins.add(Coin())
score = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    player.update()
    coins.update()

    screen.fill((20, 22, 40))
    coins.draw(screen)
    screen.blit(player.image, player.rect)
    text = font.render(f"Score: {score}", True, (240, 240, 240))
    screen.blit(text, (10, 10))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Sprites and Images

Practice on your own: Pygame playground