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

Python Arcade游戏菜单场景敌人生成计时器触发崩溃修复

问题根源

崩溃由两个逻辑缺陷共同导致:

  1. 敌人生成计时器、刷怪逻辑写在场景判断分支外部,菜单场景下计时器仍在后台累计时间
  2. 菜单阶段setup()方法未执行,enemy_list为None,一旦计时器达到刷怪阈值,代码尝试向不存在的列表追加精灵实例,直接触发属性错误崩溃。
修复方案

按照以下三点修改即可彻底解决问题:

  • 将所有计时累加、时间计算、敌人生成的逻辑,整体移动到SCENE_GAME的判断分支内部,菜单场景下完全不执行刷怪相关逻辑,从执行路径上切断菜单阶段触发刷怪的可能
  • 点击开始按钮进入游戏时,重置刷怪计时器、每波敌人数、刷怪间隔三个参数的初始值,避免程序启动后菜单停留的累计时间带入游戏局内,导致刚进游戏就瞬间刷怪
  • 在游戏场景逻辑最前端加一层防御校验,判断核心精灵列表是否已初始化,避免后续其他场景切换逻辑出问题时再次触发同类崩溃
具体代码修改

首先修改开始按钮的点击回调,加入参数重置逻辑:

def on_click_start(self, event):
    self.setup()
    # 重置刷怪相关参数,避免菜单阶段的残留值影响新局
    self.total_time = 0.0
    self.enemy_count = 1
    self.enemy_diff = 3
    self.scene = SCENE_GAME
    self.manager.disable()
    print("Start:", event)

然后修改on_update方法,把原本在场景判断外的计时、刷怪逻辑全部移入游戏场景分支,同时加入防御校验:

def on_update(self, delta_time):
    """ updates values n stuff """

    if self.scene == SCENE_GAME:
        # 防御校验:核心精灵列表未初始化时直接返回,避免崩溃
        if not self.player_list or not self.enemy_list or not self.bullet_list:
            return

        # call update to move the sprite
        self.player_list.update()

        # Call update on all sprites
        self.bullet_list.update()

        # go through each bullet
        for bullet in self.bullet_list:

            # check each bullet to see if it hit a zombie
            hit_list = arcade.check_for_collision_with_list(bullet, self.enemy_list)

            # if it did, remove the bullet
            if len(hit_list) > 0:
                bullet.remove_from_sprite_lists()

            # for each enemy we hit with a bullet, remove enemy and add to the score
            for enemy in hit_list:
                enemy.remove_from_sprite_lists()
                self.score += 1

            # if bullet goes off screen, then remove it
            if bullet.bottom > self.width or bullet.top < 0 or bullet.right < 0 or bullet.left > self.width:
                bullet.remove_from_sprite_lists()

        for enemy in self.enemy_list:
            Enemy.follow_sprite(enemy, self.player_sprite)

        # create a list of all sprites that had a collision with the player.
        hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.enemy_list)

        # go through each sprite, if it got hit, then remove the sprite and lower score and health
        for enemy in hit_list:
            enemy.remove_from_sprite_lists()
            self.score -= 1
            self.health -= 1

        # 仅在游戏场景下累计刷怪时间
        self.total_time += delta_time

        # Calculate minutes
        minutes = int(self.total_time) // 60

        # Calculate seconds by using a modulus (remainder)
        seconds = int(self.total_time) % 60

        # Calculate 100s of a second
        seconds_100s = int((self.total_time - seconds) * 100)


        if self.total_time > self.enemy_diff:
            for i in range(self.enemy_count):
                # enemy texture
                enemy = arcade.Sprite(":resources:images/animated_characters/zombie/zombie_idle.png", SPRITE_SCALING)

                enemy.center_x = random.randrange(SCREEN_WIDTH)
                enemy.center_y = random.randrange(SCREEN_HEIGHT)

                self.enemy_list.append(enemy)
            self.total_time = 0.0
            self.enemy_diff -= 0.005
            self.enemy_count += 1
可选优化
  • 当前敌人会完全随机生成在屏幕任意位置,可能直接刷在玩家出生点导致瞬间掉血,可以在生成敌人时计算和玩家坐标的距离,距离小于200像素时重新随机生成位置
  • 现有鼠标点击退出的逻辑没有场景判断,菜单下点击鼠标也会直接触发退出,可以给死亡退出逻辑加上self.scene == SCENE_GAME and self.health <=0的前置判断
  • 刷怪间隔不要无限制缩短,可以加个最小值判断,比如self.enemy_diff降到0.5秒就不再减少,避免后期刷怪速度太快导致游戏完全无法进行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:15:12