使用 Sprite 组时 Sprite 移动不起作用

Sprite movement not working when using Sprite groups

游戏的重点是敌人向你移动,如果锤子与他们相撞,他们就会消失。但由于某种原因,敌人要么不动,要么在被击中时不消失。这是检查碰撞的代码:

if len(enemy_group) <= 0:
    enemy = Enemy(random.randint(0, 1000), random.randint(0, 700))
    enemy_group.add(enemy)

for enemy in enemy_group:
    enemy.move(player.x, player.y)
    if pygame.sprite.spritecollide(hammer, enemy_group, True):
        move_away, move_back = False, True

enemy_group.draw(screen)

此代码确实会移除被击中的敌人,但它们不会向玩家移动。相反,如果我这样做:

if len(enemy_group) <= 0:
    enemy = Enemy(random.randint(0, 1000), random.randint(0, 700))
    enemy_group.add(enemy)

for enemy in enemy_group:
    enemy.move(player.x, player.y)
    enemy.draw(screen)
    if pygame.sprite.spritecollide(hammer, enemy_group, True):
        move_away, move_back = False, True

然后敌人向玩家移动,但被击中后并没有消失。我不能让他们同时做这两件事。

如果需要的话,这里有锤子和敌人类:

class Hammer:
    def __init__(self, x, y, image):
        self.image = image
        self.x = x
        self.y = y
        self.rect = self.image.get_rect(center = (self.x, self.y))
        self.rot = 0

    def draw(self, screen):
        screen.blit(self.rot_image, (self.rect))

    def get_movement_hammer(self, x, y):
        dirx, diry = x - self.x, y - self.y
        direc = dirx, diry
        
        length = math.hypot(*direc)

        if length == 0.0:
            dirx, diry = 0, -1
                
        else: 
            dirx, diry = dirx/length, diry/length

        return dirx, diry

    def move_hammer(self, dirx, diry, xspeed, yspeed):
        self.rot_speed = 15
        self.rot = (self.rot + self.rot_speed) % 360
        self.rot_image = pygame.transform.rotozoom(self.image, self.rot, 1)
        self.rect = self.rot_image.get_rect(center = (self.x, self.y))
        
        self.x += (dirx * xspeed)      
        self.y += (diry * yspeed)


class Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)

        self.x = x
        self.y = y
        self.image = enemy_image
        self.rect = self.image.get_rect(center = (self.x, self.y))

    def move(self, px, py):
        dirx, diry = px - self.x, py - self.y
        direc = dirx, diry
        
        length = math.hypot(*direc)

        if length == 0.0:
            dirx, diry = 0, -1
                
        else: 
            dirx, diry = dirx/length, diry/length

        self.x += dirx * 2
        self.y += diry * 2

    def draw(self, screen):
        screen.blit(self.image, (self.x, self.y))

阅读文档 pygame.sprite.Group.draw():

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect for the position.

rect 属性也用于碰撞检测(例如 pygame.sprite.spritecollide)。因此,移动后需要更新敌人的rect属性:

class Enemy(pygame.sprite.Sprite):
    # [...]

     def move(self, px, py):
        dirx, diry = px - self.x, py - self.y
        direc = dirx, diry
        
        length = math.hypot(*direc)

        if length == 0.0:
            dirx, diry = 0, -1
                
        else: 
            dirx, diry = dirx/length, diry/length

        self.x += dirx * 2
        self.y += diry * 2

        self.rect.center = round(self.x), round(self.y)  # <---

    # [...]