具有透明背景的精灵的像素完美碰撞检测

发布于 2021-01-29 15:05:35

如何使用Pygame的sprite模块检测具有透明背景的两个精灵的碰撞,以便True仅在实际的精灵(而不是透明背景)碰撞时返回?

关注者
0
被浏览
76
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    使用该pygame.mask.from_surface函数为您的精灵赋予self.mask属性。

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

    然后,您可以将pygame.sprite.collide_mask回调函数传递给sprite碰撞函数之一,例如pygame.sprite.spritecollide,碰撞检测将是完美的像素。

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

    这是一个完整的示例(当两个精灵碰撞时,标题会更改):

    import pygame as pg
    
    
    class Player(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)
    
    
    class Enemy(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)
    
    
    class Game:
        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()
    
        def run(self):
            while not self.done:
                self.event_loop()
                self.update()
                self.draw()
                pg.display.flip()
                self.clock.tick(60)
    
        def event_loop(self):
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    self.done = True
                elif event.type == pg.MOUSEMOTION:
                    self.player.rect.center = event.pos
    
        def update(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')
    
        def draw(self):
            self.screen.fill((30, 30, 30))
            self.all_sprites.draw(self.screen)
    
    
    if __name__ == '__main__':
        pg.init()
        game = Game()
        game.run()
        pg.quit()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看