You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建第二个Enemy对象触发AttributeError:无get_rect属性

问题:创建第二个Enemy精灵对象时触发AttributeError

开发小游戏时,尝试从Enemy类创建两个对象并加入精灵组,创建第二个对象时出现错误:AttributeError: 'Enemy' object has no attribute 'get_rect'。尝试用enemy2 = enemy的方式创建,结果仅得到同一个对象,相关代码如下:

class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = enemy
        self.rect = self.image.get_rect()
        self.rect.center = (200, 200)
        self.speedx = random.randint(1, 10)
        self.speedy = random.randint(1, 10)
        self.collis = 0
        self.enemy_health = 5
        self.enemy_rect = pygame.rect.Rect((self.rect.x + 35, self.rect.y + 20), (35, 15))
        self.skin = 0
        self.skin_index = 0
        self.skins = [enemy, enemy_1, enemy_2]
        self.left_skins = [pygame.transform.flip(self.skins[0], True, False),
                           pygame.transform.flip(self.skins[1], True, False),
                           pygame.transform.flip(self.skins[2], True, False)]
        self.move_enemy = 1

    def update(self, collis):

        self.enemy_rect = pygame.rect.Rect((self.rect.x + 35, self.rect.y + 20), (35, 15))
        if self.move_enemy == 1:
            if self.collis < 1:
                self.speedx = random.randint(1, 2)
                self.speedy = random.randint(1, 2)
                if player.player_x_pos > self.rect.x:
                    self.rect.x += self.speedx
                    self.skin += 1
                    if self.skin % 10 == 0:
                        self.skin_index += 1
                        if self.skin_index > 2:
                            self.skin_index = 0
                    self.image = self.skins[self.skin_index]

                if player.player_y_pos + 50 > self.rect.y:
                    self.rect.y += self.speedy
                    self.skin += 1
                    if self.skin % 10 == 0:
                        self.skin_index += 1
                        if self.skin_index > 2:
                            self.skin_index = 0
                    self.image = self.skins[self.skin_index]

                if player.player_x_pos < self.rect.x:
                    self.rect.x -= self.speedx
                    self.skin += 1
                    if self.skin % 10 == 0:
                        self.skin_index += 1
                        if self.skin_index > 2:
                            self.skin_index = 0
                    self.image = self.left_skins[self.skin_index]

                if player.player_y_pos + 50 < self.rect.y:
                    self.rect.y -= self.speedy
                    self.skin += 1
                    if self.skin % 10 == 0:
                        self.skin_index += 1
                        if self.skin_index > 2:
                            self.skin_index = 0
                    if player.player_x_pos < self.rect.x:
                        self.image = self.left_skins[self.skin_index]
                    else:
                        self.image = self.skins[self.skin_index]

            else:
                self.collis = 0
            # if self.enemy_health <= 0:
            #     del enemy
            print('Health:', self.enemy_health)
        if self.move_enemy == 2:
            if self.rect.y <= 550:
                self.rect.y += 2
            else:
                self.rect.y -= 2

enemy = Enemy()
enemy2 = Enemy()
enemy2.rect.center = (100, 100)
scene_1_sprites.add(enemy2)
scene_1_sprites.add(enemy)

错误原因

  1. 变量名冲突:类内部self.image = enemy和skins = [enemy, enemy_1, enemy_2]中的enemy,原本应该指向pygame Surface格式的图像资源,但后续用enemy = Enemy()将该变量赋值为Enemy对象实例。第一次创建对象时,enemy变量还未被赋值为对象,可能凑巧能运行,但第二次创建enemy2 = Enemy()时,enemy已经是Enemy对象,把对象赋值给self.image后,调用self.image.get_rect()自然会报错——Enemy对象没有get_rect()方法,只有pygame Surface才有。
  2. 对象引用错误:enemy2 = enemy只是复制了对象的引用,两个变量指向同一个实例,所以看起来只有一个对象。

修复方案

1. 重命名图像资源变量

把图像资源的变量名改成和对象变量不冲突的名称,比如enemy_img、enemy_img_1、enemy_img_2,确保类内部引用的是Surface资源而非对象实例。

2. 正确创建独立对象

保持用enemy2 = Enemy()的方式创建第二个对象,每次调用类构造函数都会生成全新的独立实例。

修改后的核心代码示例

# 先加载图像资源(修正变量名)
enemy_img = pygame.image.load("enemy.png").convert_alpha()
enemy_img_1 = pygame.image.load("enemy_1.png").convert_alpha()
enemy_img_2 = pygame.image.load("enemy_2.png").convert_alpha()

class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        # 引用修正后的图像资源变量
        self.image = enemy_img
        self.rect = self.image.get_rect()
        self.rect.center = (200, 200)
        self.speedx = random.randint(1, 10)
        self.speedy = random.randint(1, 10)
        self.collis = 0
        self.enemy_health = 5
        self.enemy_rect = pygame.rect.Rect((self.rect.x + 35, self.rect.y + 20), (35, 15))
        self.skin = 0
        self.skin_index = 0
        # 替换skins中的变量名
        self.skins = [enemy_img, enemy_img_1, enemy_img_2]
        self.left_skins = [pygame.transform.flip(self.skins[0], True, False),
                           pygame.transform.flip(self.skins[1], True, False),
                           pygame.transform.flip(self.skins[2], True, False)]
        self.move_enemy = 1

    # update方法保持不变...

# 创建两个独立的Enemy对象
enemy = Enemy()
enemy2 = Enemy()
enemy2.rect.center = (100, 100)
scene_1_sprites.add(enemy2)
scene_1_sprites.add(enemy)

额外提示

  • 确保图像资源在Enemy类定义前完成加载,避免变量未定义错误。
  • 永远不要通过引用赋值的方式创建新精灵,必须通过类实例化生成独立对象。

内容的提问来源于stack exchange,提问作者Lambert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:25:26