《外星人入侵》AttributeError求助:Scoreboard对象无level_image属性
问题排查:《外星人入侵》Scoreboard类AttributeError问题
编写《外星人入侵》游戏时遇到AttributeError,提示'Scoreboard'对象没有'level_image'属性,对照《Python Crash Course》代码修改后仍未解决,怀疑prep_high_score调用存在问题。
报错栈信息
Traceback (most recent call last): File "c:\Users\hlehm\Onedrive Transfer\Python\Projects\Alien_Invasion\alien_invasion.py", line 272, in <module> ai.run_game() File "c:\Users\hlehm\Onedrive Transfer\Python\Projects\Alien_Invasion\alien_invasion.py", line 50, in run_game self._update_screen() File "c:\Users\hlehm\Onedrive Transfer\Python\Projects\Alien_Invasion\alien_invasion.py", line 258, in _update_screen self.sb.show_score() File "c:\Users\hlehm\Onedrive Transfer\Python\Projects\Alien_Invasion\scoreboard.py", line 75, in show_score self.screen.blit(self.level_image, self.level_rect) AttributeError: 'Scoreboard' object has no attribute 'level_image'
原始Scoreboard类代码
import pygame.font class Scoreboard: """A class to report scoring information""" def __init__(self, ai_game): """Initialize scorekeeping attributes""" self.screen = ai_game.screen self.screen_rect = self.screen.get_rect() self.settings = ai_game.settings self.stats = ai_game.stats #Font settings for scoring information self.text_color = (30, 30, 30) self.font = pygame.font.SysFont(None, 48) #Prepare the initial score images self.prep_score() self.prep_high_score() def prep_score(self): """Turn the score into a render image""" rounded_score = round(self.stats.score, -1) score_str = "{:,}".format(rounded_score) self.score_image = self.font.render(score_str, True, self.text_color, self.settings.bg_color) #Display the score at the top right of the screen self.score_rect = self.score_image.get_rect() self.score_rect.right = self.screen_rect.right - 20 self.score_rect.top = 20 def prep_high_score(self): """Turn the high score into a rendered image""" high_score = round(self.stats.high_score, -1) high_score_str = "{:,}".format(high_score) self.high_score_image = self.font.render( high_score_str, True, self.text_color, self.settings.bg_color) #Center the high score at the top of the screen self.high_score_rect = self.high_score_image.get_rect() self.high_score_rect.centerx = self.screen_rect.centerx self.high_score_rect.top = self.screen_rect.top def check_high_score(self): """Check to see if there's a new high score""" if self.stats.score > self.stats.high_score: self.stats.high_score = self.stats.score self.prep_high_score() self.prep_level() def prep_level(self): """Turn the level into a rendered image""" level_str = str(self.stats.level) self.level_image = self.font.render( level_str, True, self.text_color, self.settings.bg_color) #Posistion the level below the score self.level_rect = self.level_image.get_rect() self.level_rect.right = self.score_rect.right self.level_rect.top = self.score_rect.bottom + 10 def show_score(self): """Draw scores and level to the screen""" self.screen.blit(self.score_image, self.score_rect) self.screen.blit(self.high_score_image, self.high_score_rect) self.screen.blit(self.level_image, self.level_rect)
问题根源与修复方案
核心问题1:类方法缩进错误
所有类方法(__init__、prep_score等)都未缩进至Scoreboard类的范围内,导致这些方法是全局函数而非类的成员方法。因此Scoreboard实例无法访问这些方法,自然不会执行prep_level创建level_image属性。
核心问题2:初始化时未调用prep_level
即使修复缩进,原始__init__方法仅调用了prep_score和prep_high_score,未调用prep_level,游戏启动后第一次执行show_score时,level_image尚未被创建,依然会报错。
修复后的完整代码
import pygame.font class Scoreboard: """用于显示得分信息的类""" def __init__(self, ai_game): """初始化得分统计属性""" self.screen = ai_game.screen self.screen_rect = self.screen.get_rect() self.settings = ai_game.settings self.stats = ai_game.stats # 得分信息的字体设置 self.text_color = (30, 30, 30) self.font = pygame.font.SysFont(None, 48) # 准备初始的得分图像 self.prep_score() self.prep_high_score() self.prep_level() # 添加该行,初始化等级图像 def prep_score(self): """将得分转换为渲染图像""" rounded_score = round(self.stats.score, -1) score_str = "{:,}".format(rounded_score) self.score_image = self.font.render(score_str, True, self.text_color, self.settings.bg_color) # 将得分显示在屏幕右上角 self.score_rect = self.score_image.get_rect() self.score_rect.right = self.screen_rect.right - 20 self.score_rect.top = 20 def prep_high_score(self): """将最高分转换为渲染图像""" high_score = round(self.stats.high_score, -1) high_score_str = "{:,}".format(high_score) self.high_score_image = self.font.render( high_score_str, True, self.text_color, self.settings.bg_color) # 将最高分居中显示在屏幕顶部 self.high_score_rect = self.high_score_image.get_rect() self.high_score_rect.centerx = self.screen_rect.centerx self.high_score_rect.top = self.screen_rect.top def check_high_score(self): """检查是否诞生了新的最高分""" if self.stats.score > self.stats.high_score: self.stats.high_score = self.stats.score self.prep_high_score() self.prep_level() def prep_level(self): """将等级转换为渲染图像""" level_str = str(self.stats.level) self.level_image = self.font.render( level_str, True, self.text_color, self.settings.bg_color) # 将等级放在得分下方 self.level_rect = self.level_image.get_rect() self.level_rect.right = self.score_rect.right self.level_rect.top = self.score_rect.bottom + 10 def show_score(self): """在屏幕上绘制得分、最高分和等级""" self.screen.blit(self.score_image, self.score_rect) self.screen.blit(self.high_score_image, self.high_score_rect) self.screen.blit(self.level_image, self.level_rect)
修复说明
- 将所有方法缩进至
Scoreboard类内部(每个方法前添加4个空格),确保它们属于类的成员方法; - 在
__init__方法末尾添加self.prep_level(),确保游戏启动时就创建level_image和level_rect属性,避免首次调用show_score时出现属性不存在的错误。
内容的提问来源于stack exchange,提问作者Plasmaneer
相关产品推荐
相关产品推荐

