如何在同一个pygame.sprite.Group中制作相互击中的BOTH子弹?

时间:2017-09-14 17:32:35

标签: python pygame sprite

我有一个名为Bullets的类,当使用pygame.sprite.spritecollide()命中它们时,这些对象能够销毁其他精灵。我的问题是我希望子弹“取消”,即在击中时互相摧毁,但是spritecollide()只杀死其中一个,我需要两个都去掉。有没有办法用spritecollide()执行此操作,还是需要其他内容?

1 个答案:

答案 0 :(得分:1)

您可以将自定义回调函数作为pygame.sprite.spritecollide参数传递给groupcollidecollided。在这种情况下,我使用groupcollide并将bullets组传递两次。 bullet_collision回调函数的目的是检查两个精灵不是同一个对象。

import pygame as pg
from pygame.math import Vector2


pg.init()

BG_COLOR = pg.Color('gray12')
BULLET_IMG = pg.Surface((9, 15))
BULLET_IMG.fill(pg.Color('aquamarine2'))


class Bullet(pg.sprite.Sprite):

    def __init__(self, pos, *sprite_groups):
        super().__init__(*sprite_groups)
        self.image = BULLET_IMG
        self.rect = self.image.get_rect(center=pos)
        self.pos = pg.math.Vector2(pos)
        self.vel = pg.math.Vector2(0, -450)

    def update(self, dt):
        self.pos += self.vel * dt
        self.rect.center = self.pos
        if self.rect.bottom <= 0 or self.rect.top > 600:
            self.kill()


# Pass this callback function to `pg.sprite.groupcollide` to
# replace the default collision function.
def bullet_collision(sprite1, sprite2):
    """Return True if sprites are colliding, unless it's the same sprite."""
    if sprite1 is not sprite2:
        return sprite1.rect.colliderect(sprite2.rect)
    else:  # Both sprites are the same object, so return False.
        return False


class Game:

    def __init__(self):
        self.clock = pg.time.Clock()
        self.screen = pg.display.set_mode((800, 600))

        self.all_sprites = pg.sprite.Group()
        self.bullets = pg.sprite.Group()

        self.done = False

    def run(self):
        while not self.done:
            dt = self.clock.tick(30) / 1000
            self.handle_events()
            self.run_logic(dt)
            self.draw()

    def handle_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.done = True
            if event.type == pg.MOUSEBUTTONDOWN:
                if event.button == 1:
                    Bullet(pg.mouse.get_pos(), self.all_sprites, self.bullets)
                    # A second bullet with inverted velocity.
                    bullet2 = Bullet(pg.mouse.get_pos()-Vector2(0, 400),
                                     self.all_sprites, self.bullets)
                    bullet2.vel = pg.math.Vector2(0, 450)

    def run_logic(self, dt):
        self.all_sprites.update(dt)
        # Groupcollide with the same group.
        # Pass the bullet_collision function as the `collided` argument.
        hits = pg.sprite.groupcollide(
            self.bullets, self.bullets,
            True, True, collided=bullet_collision)

    def draw(self):
        self.screen.fill(BG_COLOR)
        self.all_sprites.draw(self.screen)

        pg.display.flip()


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