Python Arcade 2D僵尸射击游戏添加GUI按钮报AttributeError
问题根因
- 你把主菜单UI的
UIManager(也就是代码里的self.manager)初始化逻辑全部写在了独立的MyWindow类中,但程序入口main()函数实际实例化运行的是MyGame类窗口,MyWindow从未被调用,其中初始化manager的代码压根没有执行。 MyGame类的__init__方法中从未定义self.manager属性,却在on_draw方法中直接调用self.manager.draw(),必然触发属性不存在的报错。- 额外逻辑缺陷:你写的
on_click_start方法仅打印日志,没有实现菜单隐藏、游戏启动的状态切换,就算修复属性问题,点击开始按钮也无法进入游戏。
修复步骤
- 删除无用的
MyWindow类,将UI初始化逻辑整合到MyGame类中 - 给
MyGame增加状态标记,区分「主菜单」「游戏中」两种状态,避免菜单和游戏内容同时渲染 - 补全按钮点击的状态切换逻辑
具体代码修改
修改MyGame类的__init__方法
在原有初始化逻辑末尾添加UI和状态相关初始化代码:
def __init__(self, width, height, title): super().__init__(width, height, title) # 保留原有精灵列表、按键状态、背景色等初始化代码不变 self.player_list = None self.player_sprite = None self.left_pressed = False self.right_pressed = False self.up_pressed = False self.down_pressed = False arcade.set_background_color(arcade.color.AMAZON) # --- 新增内容开始 --- # 游戏状态标记:False=显示主菜单,True=进入游戏 self.game_started = False # 初始化UI管理器 self.manager = arcade.gui.UIManager() self.manager.enable() # 创建垂直布局容器排列按钮 self.v_box = arcade.gui.UIBoxLayout() # 创建三个功能按钮 start_button = arcade.gui.UIFlatButton(text="开始游戏", width=200) self.v_box.add(start_button.with_space_around(bottom=20)) settings_button = arcade.gui.UIFlatButton(text="设置", width=200) self.v_box.add(settings_button.with_space_around(bottom=20)) quit_button = QuitButton(text="退出", width=200) self.v_box.add(quit_button) # 绑定按钮事件 start_button.on_click = self.on_click_start @settings_button.event("on_click") def on_click_settings(event): print("打开设置面板") # 将按钮容器固定到窗口居中位置 self.manager.add( arcade.gui.UIAnchorWidget( anchor_x="center_x", anchor_y="center_y", child=self.v_box ) ) # --- 新增内容结束 ---
修改开始按钮点击方法
替换原有的空实现,加入状态切换逻辑:
def on_click_start(self, event): self.game_started = True # 禁用UI管理器,隐藏主菜单 self.manager.disable() # 加载游戏资源、初始化游戏内容 self.setup()
修改on_draw渲染逻辑
按状态分别渲染菜单/游戏内容,避免未启动游戏时调用精灵绘制逻辑报错:
def on_draw(self): self.clear() if not self.game_started: # 主菜单状态仅渲染UI self.manager.draw() else: # 游戏状态渲染所有精灵和文字 self.player_list.draw() self.enemy_list.draw() self.bullet_list.draw() output = f"Score: {self.score}" arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14) output = f"Health: {self.health}" arcade.draw_text(output, 10, 40, arcade.color.WHITE, 14) if self.health <= 0: self.player_sprite.remove_from_sprite_lists() output = f"YOU DIED" arcade.draw_text(output, 500, 400, arcade.color.RED, 50) output = f"Click to Exit" arcade.draw_text(output, 550, 300, arcade.color.BLACK, 30)
修改程序入口
删除启动时主动调用setup()的逻辑,改为点击开始按钮后再初始化游戏内容:
def main(): window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) arcade.run()
改完后运行程序,会先显示居中的三个菜单按钮,点击开始游戏就会隐藏菜单进入僵尸射击玩法,点击退出直接关闭程序。
内容的提问来源于stack exchange,提问作者riley
相关产品推荐
相关产品推荐

