嗨,我最近开始进入pygame库并制作了一些小项目。我正在做一个非常简单的游戏,您作为玩家必须躲避敌人。但是,当它们相互碰撞时,我想删除它们。我想到了以下代码,但是,它只删除了一个小怪。小怪既存在于all_sprites中,也存在于mob_sprites中。我对sprite和pygame还是很陌生,所以这里可能存在一个愚蠢的错误,希望有人可以帮助我。
# check mob collision
for mob in mobs:
temp_sprites.add(mob)
mobs.remove(mob)
collision = pg.sprite.groupcollide(temp_sprites, mobs, True, True)
for col in collision:
# score is just for the game
score += col.size
else:
mobs.add(mob)
all_sprites.add(mob)
temp_sprites.remove(mob)
答案 0 :(得分:1)
如果要销毁一个精灵,则只需调用pygame.sprite.Sprite.kill()
:
mob.kill()
kill
从包含该精灵的所有组中删除该精灵。
如果要检测某个小精灵是否与某个其他小精灵在循环中发生冲突,则建议使用2个嵌套循环和pygame.sprite.collide_rect()
:
例如:
for mob1 in mobs:
for mob2 in mobs:
if mob1 != mob2 and pg.sprite.collide_rect(mob1, mob2):
mob1.kill()
mob2.kill()
# score is just for the game
score += col.size
答案 1 :(得分:1)
您的第一个问题是您使用了for...else
循环;如果您在冲突时不进行else
for循环,则会执行break
部分,从而重新添加精灵。
您的代码的第二个问题是,尽管groupcollide
可以正确地将精灵从其组中删除,但由于它们仍存储在您用for
遍历的列表中,因此它们会被读取循环(遍历一个sprite组每次都会创建一个新列表)。
因此,您可以使用以下方式修复代码:
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()
使用鼠标左键放置静态矩形,使用其他鼠标键放置移动的矩形。