import { _decorator, Component, find, UITransform } from 'cc'; import { LevelSessionManager } from '../Core/LevelSessionManager'; import { SaveDataManager } from './SaveDataManager'; import EventBus, { GameEvents } from '../Core/EventBus'; import { GameManager } from './GameManager'; import { SkillManager } from '../CombatSystem/SkillSelection/SkillManager'; const { ccclass } = _decorator; /** * 游戏启动管理器 * 负责统一处理游戏启动流程:生成方块选择 → 播放diban动画 → 确认开始游戏,并加载游戏状态 * 不区分首次游戏和重启游戏,统一按照流程进行 * * 注意:这个类主要提供静态方法,不需要挂载到场景节点上 */ @ccclass('StartGame') export class StartGame extends Component { private static eventListenersInitialized = false; start() { // 初始化静态事件监听器(只初始化一次) StartGame.initializeEventListeners(); } onDestroy() { // 组件销毁时不移除静态事件监听,因为其他地方可能还需要使用 } /** * 初始化静态事件监听器 * 可以被外部调用以确保事件监听器已设置 */ public static initializeEventListeners() { if (StartGame.eventListenersInitialized) { return; } const eventBus = EventBus.getInstance(); eventBus.on(GameEvents.GAME_START, StartGame.onGameStartEvent); eventBus.on(GameEvents.GAME_RESTART, StartGame.onGameStartEvent); StartGame.eventListenersInitialized = true; console.log('[StartGame] 静态事件监听器初始化完成'); } /** * 处理游戏启动事件(统一处理首次启动和重启) */ private static onGameStartEvent() { console.log('[StartGame] 接收到游戏启动事件,开始游戏启动流程'); StartGame.startGameFlow(); } /** * 统一的游戏启动流程 * 无论是首次启动还是重启,都按照相同流程进行 * 注意:不在此处清理游戏状态,清理由GameEnd UI状态监听机制负责 */ public static async startGameFlow() { console.log('[StartGame] 开始游戏启动流程'); // 确保事件监听器已初始化 StartGame.initializeEventListeners(); const eventBus = EventBus.getInstance(); // 1. 初始化游戏数据 console.log('[StartGame] 初始化游戏数据'); await StartGame.initializeGameData(); // 2. 初始化GameBlockSelection确认回调(避免场景加载时过早设置) console.log('[StartGame] 设置GameBlockSelection确认回调'); const gameManager = GameManager.getInstance(); if (gameManager) { (gameManager as any).initGameBlockSelection(); console.log('[StartGame] GameBlockSelection确认回调设置完成'); } // 3. 设置BlockManager的gameStarted标志(在生成方块之前设置) console.log('[StartGame] 设置BlockManager的gameStarted标志'); const blockManagerNode = find('Canvas/GameLevelUI/BlockController'); if (blockManagerNode) { const blockManager = blockManagerNode.getComponent('BlockManager'); if (blockManager) { (blockManager as any).onGameStart(); console.log('[StartGame] BlockManager gameStarted标志已设置'); } else { console.warn('[StartGame] BlockManager组件未找到'); } } else { console.warn('[StartGame] BlockManager节点未找到'); } // 4. 生成初始方块(在gameStarted标志设置之后) console.log('[StartGame] 生成初始方块'); const blockSelectionUINode = find('Canvas/GameLevelUI/BlockSelectionUI'); if (blockSelectionUINode) { const gameBlockSelection = blockSelectionUINode.getComponent('GameBlockSelection'); if (gameBlockSelection) { (gameBlockSelection as any).generateBlockSelection(); console.log('[StartGame] 初始方块生成完成'); } else { console.warn('[StartGame] GameBlockSelection组件未找到'); } } else { console.warn('[StartGame] diban容器节点未找到'); } // 5. 播放diban上移动画和镜头下移动画 console.log('[StartGame] 播放diban上移动画和镜头下移动画'); const cameraNode = find('Canvas/Camera'); if (cameraNode) { const gameStartMove = cameraNode.getComponent('GameStartMove'); if (gameStartMove) { (gameStartMove as any).slideUpFromBottom(0.3); console.log('[StartGame] diban上移动画和镜头下移动画已启动'); } else { console.warn('[StartGame] GameStartMove组件未找到'); } } else { console.warn('[StartGame] Camera节点未找到'); } console.log('[StartGame] 游戏启动流程完成'); } /** * 初始化游戏数据 */ private static async initializeGameData() { // 清理并重新初始化关卡会话数据 LevelSessionManager.inst.clear(); // 初始化存档管理器 const saveDataManager = SaveDataManager.getInstance(); await saveDataManager.initialize(); // 重新初始化LevelSessionManager,从关卡配置读取initialCoins await LevelSessionManager.inst.initialize( saveDataManager.getCurrentLevel(), 100 // 默认墙血量,可以根据需要调整 ); // 计算游戏区域边界 StartGame.calculateGameBounds(); console.log('[StartGame] 游戏数据初始化完成,sessionCoins已从关卡配置读取'); // 重置游戏相关组件 const eventBus = EventBus.getInstance(); // 重置球控制器,清理上一关可能残留的球 eventBus.emit(GameEvents.RESET_BALL_CONTROLLER); console.log('[StartGame] 发送球控制器重置事件,清理上一关残留的球'); // 先重置能量为0 eventBus.emit(GameEvents.RESET_ENERGY_SYSTEM); console.log('[StartGame] 发送能量重置事件'); // 重置技能选择数据(清空三选一技能等级) const skillManager = SkillManager.getInstance(); if (skillManager) { skillManager.resetAllSkillLevels(); console.log('[StartGame] 技能选择数据已重置'); } // 延迟加载关卡配置,确保能量重置先执行 setTimeout(async () => { // 获取GameManager实例并加载关卡配置 const gameManagerNode = find('GameManager'); if (gameManagerNode) { const gameManager = gameManagerNode.getComponent(GameManager); if (gameManager && gameManager.loadCurrentLevelConfig) { await gameManager.loadCurrentLevelConfig(); console.log('[StartGame] 关卡配置加载完成'); } } }, 100); } /** * 计算游戏区域边界 */ private static calculateGameBounds() { const canvas = find('Canvas'); if (!canvas) { console.warn('[StartGame] 未找到Canvas节点'); return; } const canvasUI = canvas.getComponent(UITransform); if (!canvasUI) { console.warn('[StartGame] Canvas节点缺少UITransform组件'); return; } const screenWidth = canvasUI.width; const screenHeight = canvasUI.height; const worldPos = canvas.worldPosition; const gameBounds = { left: worldPos.x - screenWidth / 2, right: worldPos.x + screenWidth / 2, bottom: worldPos.y - screenHeight / 2, top: worldPos.y + screenHeight / 2 }; console.log('[StartGame] 游戏区域边界计算完成:', gameBounds); } /** * 通过事件系统重置能量值 */ public static resetEnergy() { const eventBus = EventBus.getInstance(); eventBus.emit(GameEvents.RESET_ENERGY_SYSTEM); console.log('[StartGame] 发送能量重置事件'); } }