您的第一个问题是您使用了for...else 循环;如果你不break for 循环以防发生冲突,else 部分将被执行,从而重新添加精灵。
您的代码的第二个问题是,虽然 groupcollide 将正确地从它们的组中删除精灵,但它们将被读取,因为它们仍然存储在您使用 for 循环迭代的列表中(迭代一个精灵组每次都会创建一个新列表)。
因此,您可以使用以下方式修复您的代码:
for mob in mobs.sprites():
if not mob.groups():
# mob was already removed by a previous iteration of this loop
continue
temp_sprites.add(mob)
mobs.remove(mob)
collision = pygame.sprite.groupcollide(temp_sprites, mobs, True, True)
for col in collision:
# score is just for the game
score += col.size
break
else:
mobs.add(mob)
all_sprites.add(mob)
temp_sprites.remove(mob)
但我建议改为在精灵的update 方法中处理冲突。
def update(self):
# whatever
if pygame.sprite.spritecollide(self, self.mobs, True, collide_rect_not_self):
self.kill()
其中self.mobs 是对mobs 组的引用,collide_rect_not_self 是pygame.sprite.collide_rect 的简单包装器:
def collide_rect_not_self(a, b):
if a != b:
return pygame.sprite.collide_rect(a, b)
这是一个完整的例子:
import random
import pygame
def collide_rect_not_self(a, b):
if a != b:
return pygame.sprite.collide_rect(a, b)
class Actor(pygame.sprite.Sprite):
def __init__(self, pos, mobs, static, *grps):
super().__init__(mobs, *grps)
self.image = pygame.Surface((40, 40))
self.rect = self.image.get_rect(center=pos)
self.pos = pygame.Vector2(*pos)
self.vel = pygame.Vector2(random.randint(0, 10), random.randint(0, 10)) if not static else pygame.Vector2(0, 0)
self.mobs = mobs
def update(self):
self.pos += self.vel
if not pygame.display.get_surface().get_rect().contains(self.rect):
self.vel *= -1
self.rect.clamp_ip(pygame.display.get_surface().get_rect())
self.pos = self.rect.center
self.rect.center = self.pos
if pygame.sprite.spritecollide(self, self.mobs, True, collide_rect_not_self):
self.kill()
def main():
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((800, 600))
mobs = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
while True:
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
return
if event.type == pygame.MOUSEBUTTONDOWN:
Actor(event.pos, mobs, event.button == 1, all_sprites)
screen.fill((255, 255, 255))
all_sprites.update()
all_sprites.draw(screen)
clock.tick(30)
pygame.display.flip()
main()
使用鼠标左键放置静态矩形,使用鼠标左键放置移动矩形。