Skip to content Skip to sidebar Skip to footer

Pixel Perfect Collision Detection For Sprites With A Transparent Background

How can I use Pygame's sprite module to detect the collision of two sprites with transparent backgrounds, so that it will return True only if the actual sprites, not the transparen

Solution 1:

Use the pygame.mask.from_surface function to give your sprites a self.mask attribute.

self.mask = pygame.mask.from_surface(self.image)

Then you can pass pygame.sprite.collide_mask as the callback function to one of the sprite collision functions like pygame.sprite.spritecollide and the collision detection will be pixel perfect.

pygame.sprite.spritecollide(self.player, self.enemies, False, pygame.sprite.collide_mask)

Here's a complete example (the caption is changed when the two sprites collide):

import pygame as pg


classPlayer(pg.sprite.Sprite):

    def__init__(self, pos):
        super(Player, self).__init__()
        self.image = pg.Surface((120, 120), pg.SRCALPHA)
        pg.draw.polygon(self.image, (0, 100, 240), [(60, 0), (120, 120), (0, 120)])
        self.rect = self.image.get_rect(center=pos)
        self.mask = pg.mask.from_surface(self.image)


classEnemy(pg.sprite.Sprite):

    def__init__(self, pos):
        super(Enemy, self).__init__()
        self.image = pg.Surface((120, 120), pg.SRCALPHA)
        pg.draw.circle(self.image, (240, 100, 0), (60, 60), 60)
        self.rect = self.image.get_rect(center=pos)
        self.mask = pg.mask.from_surface(self.image)


classGame:
    def__init__(self):
        self.screen = pg.display.set_mode((640, 480))
        self.player = Player((20, 20))
        self.enemies = pg.sprite.Group(Enemy((320, 240)))
        self.all_sprites = pg.sprite.Group(self.player, self.enemies)
        self.done = False
        self.clock = pg.time.Clock()

    defrun(self):
        whilenot self.done:
            self.event_loop()
            self.update()
            self.draw()
            pg.display.flip()
            self.clock.tick(60)

    defevent_loop(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.done = Trueelif event.type == pg.MOUSEMOTION:
                self.player.rect.center = event.pos

    defupdate(self):
        # Check if the player collides with an enemy sprite. The# `pygame.sprite.collide_mask` callback uses the `mask`# attributes of the sprites for the collision detection.if pg.sprite.spritecollide(self.player, self.enemies, False, pg.sprite.collide_mask):
            pg.display.set_caption('collision')
        else:
            pg.display.set_caption('no collision')

    defdraw(self):
        self.screen.fill((30, 30, 30))
        self.all_sprites.draw(self.screen)


if __name__ == '__main__':
    pg.init()
    game = Game()
    game.run()
    pg.quit()

Post a Comment for "Pixel Perfect Collision Detection For Sprites With A Transparent Background"