我有一个名为Bullets
的类,当使用pygame.sprite.spritecollide()
命中它们时,这些对象能够销毁其他精灵。我的问题是我希望子弹“取消”,即在击中时互相摧毁,但是spritecollide()
只杀死其中一个,我需要两个都去掉。有没有办法用spritecollide()
执行此操作,还是需要其他内容?
答案 0 :(得分:1)
您可以将自定义回调函数作为pygame.sprite.spritecollide
参数传递给groupcollide
或collided
。在这种情况下,我使用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()