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"