Pygame 当子弹击中敌人时给我一个错误

Pygame giving me a error when a bullet hits an enemy

我正在制作一个坦克游戏,你可以向其他坦克发射子弹。但是当你的子弹击中敌人时,我会得到这样的错误:

Traceback (most recent call last):
  File "...", line 182, in <module>
    if pygame.sprite.spritecollide(i, enemy_group, True):
  File "...\pygame\sprite.py", line 1645, in spritecollide
    default_sprite_collide_func = sprite.rect.colliderect
AttributeError: 'Bullet' object has no attribute 'rect'

这是我代码中的问题,还是 pygame 中的问题?

这是子弹class:(顺便说一句,子弹过载class)

class Bullet(Projectile):
    def __init__(self, *, screen, image):
        Projectile.__init__(self)

        self._screen = screen
        self._x = tank.get("x") + 90
        self._y = tank.get("y") - 7
        self._image = pygame.image.load(image)
        self._rect = self._image.get_rect()

    def update(self, speed):
        if self._x >= 800 or self._x <= 0:
            self.kill()

        self._x += speed
        self._rect.center = (self._x, self._y)

    def blit_on_screen(self):
        self._screen.blit(self._image, self._rect)

(射弹 class 只是一个 class 抽象方法等待被子弹 class 重载。)

还有,敌人来了class:

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

        self._screen = screen
        self._x = x
        self._y = y

        self._image = pygame.image.load("assets/Tank.png")
        self._image = pygame.transform.flip(self._image, True, False)
        self._image = pygame.transform.scale(self._image, (490, 280))

        self._rect = self._image.get_rect()

    def update(self, speed):
        if self._x <= 0 or self._x >= 800:
            self.kill()

        self._x -= speed
        self._rect.center = (self._x, self._y)

    def blit_on_screen(self):
        self._screen.blit(self._image, self._rect)

这是检查碰撞子弹和敌人的部分:

    for i in bullet_group:
        if pygame.sprite.spritecollide(i, enemy_group, True):
            logging.info("bullet and enemy collided")

这里发生了什么?

pygame.sprite.spritecollide 使用 .rect 属性来检测冲突。请参阅 pygame.sprite.spritecollide

的文档

[...] If collided is not passed, all sprites must have a "rect" value, which is a rectangle of the sprite area, which will be used to calculate the collision.

因此您必须将属性命名为 rect 而不是 _rect:

class Bullet(Projectile):
    def __init__(self, *, screen, image):
        # [...]      
  
        self.rect = self._image.get_rect()
class Enemy(pygame.sprite.Sprite):
    def __init__(self, *, screen, x, y):
        # [...]

        self.rect = self._image.get_rect()

或者,您可以创建自己的碰撞检测函数。将函数传递给可选的 collided 参数:

def my_collide(a, b):
    return a._rect.colliderect(b._rect)
if pygame.sprite.spritecollide(i, enemy_group, True, collided = my_collide):
    # [...]