跳到主要内容

场景系统

相关源文件

目的与范围

场景系统是 Adventure-King 游戏流程的中央编排者(central orchestrator),管理从主菜单到实际战斗的一切玩法上下文。其重要性评分为 128.91,是代码库中优先级最高的架构组件。该系统负责:

  • 场景生命周期(创建、初始化、切换、销毁)
  • 编排玩家、怪物、关卡、UI 与输入等系统
  • 场景切换期间的资源预加载与状态恢复
  • 物理世界初始化与更新循环管理

关于由场景编排的各子系统的详细信息,请参阅:

子页面:


场景类型分类

代码库定义了一套场景类型层级,每类场景在游戏流程中承担不同职责:

场景类型用途基类关键特性
HelloWorldScene主菜单与职业选择cocos2d::Scene入口、存档槽选择、云端认证
LoadingScene资源预加载与状态恢复cocos2d::Scene异步资源加载、运行时数据搬运
MapScene关卡选择世界地图cocos2d::Scene进度追踪、关卡解锁
GameScene所有玩法关卡的基类cocos2d::Scene物理、战斗、刷怪、UI 编排
HomeScene枢纽/安全区关卡GameScene玩家安全探索
具体关卡场景特定战斗关卡GameSceneTMX 地图、怪物波次、Boss 战
DebugScene开发者测试沙盒cocos2d::Scene隔离测试功能

来源: Classes/Scenes/GameScene.h L39

Classes/Scenes/DebugScene.h L79

图示 1(总体系统架构)


场景类层级结构

下图展示了场景类的继承结构与关键方法,并说明 GameScene 如何作为所有玩法上下文的抽象基类:


GameScene 初始化流水线

GameScene::initWithPhysicsConfig() 执行严格的初始化顺序。顺序非常关键,因为后续步骤依赖之前的准备:

关键依赖:

  1. _gameLayer 必须先于 LevelMap::load() 存在(line 152-153)
  2. 玩家物理体需要 TMX 的碰撞数据(line 174)
  3. 相机跟随需要玩家位置(line 186)
  4. UI 绑定需要玩家组件已就绪(line 192)
  5. 状态恢复必须在出生点/竞技场设置完成之后、首次 update() 之前发生(line 198-318)

来源: Classes/Scenes/GameScene.cpp L130-L326

Classes/Scenes/GameScene.h L141

图示 4(战斗与怪物系统集成)


场景生命周期状态

每个场景都会在 cocos2d::Director 的管理下经历以下状态:

生命周期方法职责:

方法调用者用途GameScene 实现
init()create()资源分配、子系统初始化调用 initWithPhysicsConfig()
onEnter()Director场景切换后收尾设置禁用 IME,从运行时缓存恢复玩家位置
update(dt)Scheduler逐帧逻辑输入 → UI → 刷怪 → 存档(见 更新循环
onExit()Director场景销毁前清理重新启用 IME

来源: Classes/Scenes/GameScene.cpp L84-L128

Classes/Scenes/DebugScene.cpp L90-L161

图示 2(场景切换流程与生命周期)


场景切换机制

场景切换通过 SceneRegistry(用于玩法关卡)与直接调用 Director::replaceScene()(用于菜单场景)来实现。下方展示了关卡场景采用的 registry 模式:

关键类与方法:

  • SceneRegistryClasses/Managers/SceneRegistry.h):管理场景元数据的单例 * registerScene(SceneID, SceneInfo):在 AppDelegate::applicationDidFinishLaunching() 期间由各场景的 setupRegistry() 静态方法调用 * getSceneIDByName(string):读档时把场景名映射为 enum * getSceneInfo(SceneID):返回包含 creator lambda 与资源列表的 SceneInfo
  • LoadingScene(见 场景切换):异步资源加载器 * createScene(SceneID):静态工厂,传入目标场景 enum * init():查询 registry、预加载资源,并在下一帧调用 creator lambda
  • 运行时数据缓存: SaveManager 为“零延迟场景切换”提供的数据桥接 * cacheRuntimePlayerData(PlayerCharacter*)GameScene::returnToMapScene() 退出前调用 * getRuntimePlayerData()GameScene::initPlayer() 恢复属性等 * setRuntimePlayerPosition(Vec2):由 load 回调设置,在 GameScene::onEnter() 消费

切换示例(读档 → 进入关卡):

1. 用户在 SaveMenuLayer 点击“读取存档”
2. 读取回调(GameScene.cpp:604-640):
- 从 SaveManager 读取 SaveSlotData
- 调用 SceneRegistry::getSceneIDByName(saveData.progressData.currentSceneName)
- 调用 SaveManager::setRuntimePlayerData(saveData.playerData)
- 调用 SaveManager::setRuntimeProgressData(saveData.progressData)
- 创建 LoadingScene::createScene(targetID)
3. LoadingScene::init()
- 查询 SceneRegistry::getSceneInfo(targetID)
- 将 sceneInfo.imagePaths 预加载进 SpriteFrameCache
- 安排调用 sceneInfo.creator()
4. LoadingScene 通过 Director::replaceScene() 切换到目标场景
5. 目标 GameScene::initWithPhysicsConfig()
- 检查 SaveManager::hasRuntimePlayerData() → 应用到玩家
- 检查 SaveManager::hasRuntimeProgressData() → 恢复刷怪状态
6. 目标 GameScene::onEnter()
- 检查 SaveManager::hasRuntimePlayerPosition() → 重定位玩家

来源: Classes/Scenes/GameScene.cpp L604-L640

Classes/Managers/SceneRegistry.h

图示 2(场景切换流程与生命周期)、图示 5(存/读档数据流架构)


子系统编排

GameScene 作为多个子系统的“指挥”,按依赖顺序初始化它们,并通过 update(dt) 循环协调交互:

更新循环优先级:

  1. 死亡覆盖(line 869-881):玩家死亡时只更新 UI 并显示死亡菜单,世界逻辑停止。
  2. 暂停覆盖(line 883-892):暂停时只更新 UI 与存档系统;物理、输入、刷怪均冻结。
  3. 输入 → UI → 战斗(line 894-914):正常流程先处理输入(更灵敏),再更新 UI,再做 Boss 清理。
  4. 刷怪管理(line 916-932):LevelMap 检查距离,生成怪物或竞技场波次。
  5. 持久化(line 934):处理即时存档请求(升级、换装等触发)与定时自动存档。

子系统依赖:

子系统初始化更新依赖所有权
PlayerCharacterinitPlayer() line 425所有玩法逻辑都依赖_player 原始指针(由场景图持有)
LevelMapinitLevelMap() line 391驱动刷怪与竞技场逻辑_levelMap unique_ptr
GameInputControllerinitInputController() line 537键盘输入 → 玩家动作_inputController unique_ptr
GameUIControllerinitUIController() line 585暂停、背包、状态条管理_uiController unique_ptr
CombatContactHelperinitPhysicsContactListener() line 524命中框碰撞的静态处理无状态(helper class)
SaveManager单例,无需 init轮询存档请求全局单例

来源: Classes/Scenes/GameScene.cpp L864-L935

Classes/Scenes/GameScene.h L216-L218

图示 6(UI 与输入控制流)


DebugScene:隔离测试环境

DebugScene 是用于开发/调试的专用场景:它复用 GameScene 的子系统(输入、UI、物理),但跳过关卡加载,从而提供可控的测试环境。它体现了:

  • 不依赖 TMX 地图的手动物理搭建
  • 直接实例化怪物用于战斗测试
  • 用于实时检查属性的 Debug UI
  • GameUIControllerGameInputController 的集成(与 GameScene 一致)

与 GameScene 的关键差异:

维度GameSceneDebugScene
基类cocos2d::Scene → 虚拟 GameScenecocos2d::Scene(无继承)
地图加载LevelMap 解析 TMXinitPlatforms() 创建静态盒体
玩家创建initPlayer() 使用 TMX 出生点initPlayer() 固定位置
怪物生成LevelMap::updateEnemySpawns() 基于距离initTestMonsters() 预放置 TrainingDummyMonster
UI完整 GameUIController相同 GameUIController + 调试面板
场景注册通过 setupRegistry() 注册可选注册(主要用于测试 LoadingScene)

架构模式:

DebugScene 不继承 GameScene,而是 组合 复用相同子系统(_inputController_uiController_gameLayer)。这表明这些子系统是可复用组件,而不是与 GameScene 的继承体系强绑定。

来源: Classes/Scenes/DebugScene.cpp L90-L144

Classes/Scenes/DebugScene.h L79-L302

图示 1(总体系统架构)


与其他系统的集成点

场景系统是各大子系统的集成中枢。下面列出关键触点:

玩家系统

  • 创建: GameScene::initPlayer() 实例化 PlayerCharacter,应用职业缩放并配置物理体
  • 状态恢复: 若存在运行时缓存,则在 initPlayer() 中调用 SaveManager::applyPlayerData()
  • 回调: 玩家死亡在 update() 中触发 GameUIController::showDeathMenu()

组件细节参见 PlayerCharacter

怪物系统

  • 工厂方法: GameScene::createMonsterByType(string)(line 795-852)将类型字符串映射到具体怪物类
  • 刷怪编排: LevelMap::updateEnemySpawns() 每帧调用,并传入 createMonsterByType lambda
  • Boss 绑定: 创建 GobluMonster 时触发 GameUI::bindBoss() 用于显示血条

AI 与战斗细节参见 MonsterBase

关卡系统

  • TMX 加载: LevelMap::load() 解析 Tiled 地图,提取刷怪点、传送门区域与碰撞几何
  • 竞技场管理: LevelMap::updateArenas() 处理波次战斗、闸门锁定与相机控制
  • 通关追踪: LevelMap::isLevelCleared() 驱动传送门解锁与关卡切换

世界管理细节参见 LevelMap

UI 系统

  • 状态管理: GameUIController 管理暂停菜单、背包层、死亡菜单优先级
  • 输入路由: GameInputController 在 ESC 键触发 GameUIController::togglePauseMenu()
  • 数据绑定: UI 组件通过 GameUI::bindPlayer()GameUI::bindBoss() 读取实时数据

交互流程参见 GameUIControllerGameInputController

持久化系统

  • 存档捕获: GameScene::fillProgressDataForSave() 导出刷怪状态、存活怪物、竞技场进度
  • 读档恢复: GameScene::initWithPhysicsConfig() 消费 SaveManager 的运行时缓存
  • 自动存档: GameScene::processSaveRequests() 每帧轮询 SaveManager::tickAutoSave()

存档结构与流程参见 SaveManager

来源: Classes/Scenes/GameScene.cpp L425-L522

Classes/Scenes/GameScene.cpp L795-L852

Classes/Scenes/GameScene.cpp L328-L389

图示 4(战斗与怪物系统集成)、图示 5(存/读档数据流架构)