Menu

Pygame Sprite Collisions: spritecollide and Masks

Check collisions between sprites and groups: spritecollide for one sprite against a group, groupcollide for two groups, dokill to remove what was hit, and pixel-perfect collisions with masks.

This page includes runnable editors. Edit, run, and see output instantly.

Once your objects are sprites in groups, one function call checks a sprite against a whole group. This game has a ship that shoots lasers at a row of enemies:

Press Play, click the game, move with the arrow keys and shoot with Space. groupcollide(lasers, enemies, True, True) finds every laser touching an enemy and removes both.

The collision functions

FunctionReturns
spritecollide(sprite, group, dokill)List of sprites in group that touch sprite
spritecollideany(sprite, group)The first sprite that touches, or None (fastest when you only need yes or no)
groupcollide(group1, group2, dokill1, dokill2)Dict: each sprite of group1 that hit, to the list of group2 sprites it hit
collide_rect(a, b)True if the rects overlap (the default test)
collide_circle(a, b)True if circles around the sprites overlap
collide_mask(a, b)True if their visible pixels overlap

dokill=True removes the sprites that collided from all their groups, which is what you want for coins and bullets. Use False when the sprite should stay, such as a wall or the player.

Every collide function takes an optional last argument, collided, which picks the test:

pygame.sprite.spritecollide(player, enemies, False, pygame.sprite.collide_circle)

Pixel-perfect collisions with masks

Rect collisions count the transparent corners of an image, so a round enemy "hits" before it visibly touches. A mask records which pixels of an image are solid, and collide_mask compares those:

Move the spike ball toward the ghost with the arrow keys. The outlines turn yellow as soon as the rectangles overlap; the background turns red only when real pixels touch.

Set self.mask once in __init__: collide_mask uses it if it exists, and otherwise builds a new mask on every check, which is slow. Rebuild it only when the image changes. Masks cost more than rects, so a common pattern is a cheap spritecollideany first, then the mask test only on the sprites it found.

Frequently Asked Questions

How do I check collisions between a sprite and a group?

hits = pygame.sprite.spritecollide(player, enemies, False) returns the list of sprites in enemies whose rects overlap the player's. Pass True instead of False to remove them from their groups as well.

How do I check collisions between two groups?

pygame.sprite.groupcollide(bullets, enemies, True, True) returns a dictionary of each bullet that hit to the enemies it hit. The two booleans say whether to kill the sprites of each group.

How do I make pixel-perfect collisions?

Pass collided=pygame.sprite.collide_mask to spritecollide. It compares the sprites' visible pixels instead of their rectangles. Give each sprite a self.mask = pygame.mask.from_surface(self.image) so the mask is not rebuilt on every check.

Coddy programming languages illustration

Learn to code with Coddy

Get started