Python外星人入侵项目AttributeError: 无_check_events属性报错修复
问题现象
运行invasion.py时抛出如下错误:
AttributeError: 'AlienInvasion' object has no attribute '_check_events'
错误根因
核心问题是Python类方法缩进错误:
_check_events方法被错误嵌套定义在run_game方法内部,不属于AlienInvasion类的直接实例方法,实例调用self._check_events()时自然找不到对应属性。_check_keydown_events、_check_keyup_events被进一步嵌套在_check_events方法内部,同样无法被类实例正常访问。- 代码还存在一个隐藏bug:
Ship类的update方法调用了self.settings.ship_speed,但Ship初始化时未保存传入的settings实例,飞船移动逻辑触发时会抛出新的属性错误。
修复方案
- 调整
invasion.py内所有类方法的缩进,把嵌套在其他方法内部的方法全部移动到AlienInvasion类的直接层级,和__init__、run_game方法保持同级缩进。 - 修改
Ship.py的初始化方法,将传入的游戏实例中的settings对象保存为Ship实例的自身属性,修复移动逻辑的参数调用问题。 settings.py代码逻辑正确,无需修改。
修复后完整代码
invasion.py
import sys import pygame from settings import Settings from ship import Ship class AlienInvasion: def __init__(self): pygame.init() self.settings = Settings() self.screen = pygame.display.set_mode( (self.settings.screen_width, self.settings.screen_height)) pygame.display.set_caption("Aliens is invading!") self.ship = Ship(self) self.bg_color = (230, 230, 230) def run_game(self): while True: self._check_events() self.ship.update() self._update_screen() def _check_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: self._check_keydown_events(event) elif event.type == pygame.KEYUP: self._check_keyup_events(event) def _check_keydown_events(self, event): if event.key == pygame.K_RIGHT: self.ship.moving_right = True elif event.key == pygame.K_LEFT: self.ship.moving_left = True def _check_keyup_events(self, event): if event.key == pygame.K_RIGHT: self.ship.moving_right = False elif event.key == pygame.K_LEFT: self.ship.moving_left = False def _update_screen(self): self.screen.fill(self.settings.bg_color) self.ship.blitme() pygame.display.flip() if __name__ == '__main__': ai = AlienInvasion() ai.run_game()
Ship.py
import pygame class Ship: def __init__(self, ai_game): self.screen = ai_game.screen self.screen_rect = ai_game.screen.get_rect() # 绑定settings属性,解决移动速度参数调用报错 self.settings = ai_game.settings self.image = pygame.image.load('images/shipdos.bmp') self.rect = self.image.get_rect() self.rect.midbottom = self.screen_rect.midbottom self.x = float(self.rect.x) self.moving_right = False self.moving_left = False def update(self): if self.moving_right and self.rect.right < self.screen_rect.right: self.x += self.settings.ship_speed if self.moving_left and self.rect.left > 0: self.x -= self.settings.ship_speed self.rect.x = self.x def blitme(self): self.screen.blit(self.image, self.rect)
内容的提问来源于stack exchange,提问作者Leo X
相关产品推荐
相关产品推荐

