import { _decorator, Component, Node, ProgressBar } from 'cc'; import EventBus, { GameEvents } from '../Core/EventBus'; import { GameBlockSelection } from '../CombatSystem/BlockSelection/GameBlockSelection'; import { Wall } from '../CombatSystem/Wall'; import { GameStartMove } from '../Animations/GameStartMove'; import { LevelSessionManager } from '../Core/LevelSessionManager'; import { SkillManager } from '../CombatSystem/SkillSelection/SkillManager'; import { BackgroundManager } from './BackgroundManager'; import { GroundBurnAreaManager } from '../CombatSystem/BulletEffects/GroundBurnAreaManager'; import { ScreenShakeManager } from '../CombatSystem/EnemyWeapon/ScreenShakeManager'; import { Audio } from '../AudioManager/AudioManager'; import { AnalyticsManager } from '../Utils/AnalyticsManager'; import { SaveDataManager } from '../LevelSystem/SaveDataManager'; import { LevelConfigManager } from './LevelConfigManager'; const { ccclass, property } = _decorator; /** * 游戏内状态枚举 * 仅在 AppState.IN_GAME 时使用 */ export enum GameState { PLAYING = 'playing', SUCCESS = 'success', DEFEAT = 'defeat', PAUSED = 'paused', BLOCK_SELECTION = 'block_selection' } /** * 游戏内状态管理器 * 负责管理游戏进行中的所有状态和逻辑 */ @ccclass('InGameManager') export class InGameManager extends Component { // === 游戏内UI节点引用 === @property({ type: Node, tooltip: '拖拽BallController节点到这里' }) public ballController: Node = null; @property({ type: Node, tooltip: '拖拽GameBlockSelection节点到这里' }) public gameBlockSelection: Node = null; @property({ type: Node, tooltip: '拖拽GameArea节点到这里' }) public gameArea: Node = null; @property({ type: Node, tooltip: '拖拽EnemyController节点到这里' }) public enemyManager: Node = null; @property({ type: Node, tooltip: '摄像机节点,用于获取GameStartMove组件' }) public cameraNode: Node = null; @property({ type: Node, tooltip: '墙体节点,用于获取Wall组件' }) public wallNode: Node = null; @property({ type: Node, tooltip: '上围栏墙体节点 (TopFence)' }) public topFenceNode: Node = null; @property({ type: Node, tooltip: '下围栏墙体节点 (BottomFence)' }) public bottomFenceNode: Node = null; // === 游戏配置属性 === // === 私有属性 === private gameStarted: boolean = false; private currentState: GameState = GameState.PLAYING; // EnemyController现在通过事件系统通信,不再直接引用 private enemySpawningStarted: boolean = false; private totalEnemiesSpawned: number = 0; private currentWave: number = 1; private currentWaveEnemyCount: number = 0; private currentWaveTotalEnemies: number = 0; public levelWaves: any[] = []; private levelTotalEnemies: number = 0; private enemiesKilled: number = 0; // === 背景管理器组件 === private backgroundManager: BackgroundManager = null; // === 地面燃烧区域管理器 === private groundBurnAreaManager: GroundBurnAreaManager = null; // 游戏计时器 private gameStartTime: number = 0; private gameEndTime: number = 0; // 游戏区域的边界 private gameBounds = { left: 0, right: 0, top: 0, bottom: 0 }; private preparingNextWave = false; // 能量系统 private energyPoints: number = 0; private energyMax: number = 0; // 必须从关卡配置中读取 private energyBar: ProgressBar = null; private selectSkillUI: Node = null; // 新增:能量条升级系统 private energyUpgradeCount: number = 0; // 当前能量条升级次数 private energyMaxUpgrades: number[] = []; // 每次升级后的最大值配置 // 能量条UI节点 @property({ type: Node, tooltip: '拖拽能量条节点到这里 (Canvas/GameLevelUI/EnergyBar)' }) public energyBarNode: Node = null; // 技能选择UI节点 @property({ type: Node, tooltip: '拖拽技能选择UI节点到这里 (Canvas/GameLevelUI/SelectSkillUI)' }) public selectSkillUINode: Node = null; // === 背景管理器 === @property({ type: Node, tooltip: '拖拽BackgroundManager节点到这里' }) public backgroundManagerNode: Node = null; @property({ type: Node, tooltip: '拖拽GroundBurnAreaManager节点到这里' }) public groundBurnAreaManagerNode: Node = null; // GameBlockSelection组件 private blockSelectionComponent: GameBlockSelection = null; private pendingSkillSelection: boolean = false; private pendingBlockSelection: boolean = false; private shouldShowNextWavePrompt: boolean = false; // 墙体组件引用 private wallComponent: Wall = null; private topFenceComponent: Wall = null; private bottomFenceComponent: Wall = null; // GameStartMove组件引用 private gameStartMoveComponent: GameStartMove = null; start() { this.initializeGameState(); this.setupEventListeners(); this.initGameBlockSelection(); this.initGameStartMove(); this.initWallComponent(); this.initUINodes(); this.initScreenShakeManager(); } onEnable() { // 旧战斗音乐播放逻辑移除,改为统一入口 // this.playBattleMusicSync(); Audio.updateBGMByTopUI(); } onDisable() { console.log('[InGameManager] GameLevelUI节点隐藏,停止战斗音乐'); // 当GameLevelUI节点隐藏时,立即停止战斗音乐 Audio.stopMusic(); } update(deltaTime: number) { } /** * 初始化游戏状态 */ private initializeGameState() { this.currentState = GameState.PLAYING; this.enemySpawningStarted = false; this.totalEnemiesSpawned = 0; this.currentWave = 1; this.currentWaveEnemyCount = 0; this.currentWaveTotalEnemies = 0; this.energyPoints = 0; this.pendingSkillSelection = false; } /** * 设置事件监听器 */ private setupEventListeners() { const eventBus = EventBus.getInstance(); eventBus.on(GameEvents.GAME_SUCCESS, this.onGameSuccessEvent, this); eventBus.on(GameEvents.GAME_DEFEAT, this.onGameDefeatEvent, this); eventBus.on(GameEvents.GAME_RESUME, this.onGameResumeEvent, this); eventBus.on(GameEvents.GAME_RESUME_SKILL_SELECTION, this.onGameResumeEvent, this); eventBus.on(GameEvents.GAME_RESUME_BLOCK_SELECTION, this.onGameResumeEvent, this); eventBus.on('ENEMY_KILLED', this.onEnemyKilledEvent, this); eventBus.on(GameEvents.RESET_ENERGY_SYSTEM, this.resetEnergySystem, this); eventBus.on(GameEvents.WALL_DESTROYED, this.onWallDestroyedEvent, this); } /** * 初始化GameBlockSelection组件 */ private initGameBlockSelection() { if (this.gameBlockSelection) { this.blockSelectionComponent = this.gameBlockSelection.getComponent(GameBlockSelection); } } /** * 初始化GameStartMove组件 */ private initGameStartMove() { if (this.cameraNode) { this.gameStartMoveComponent = this.cameraNode.getComponent(GameStartMove); } } /** * EnemyController现在通过事件系统通信,不再需要直接初始化 */ /** * 初始化墙体组件 */ private initWallComponent() { // 初始化主墙体 if (this.wallNode) { this.wallComponent = this.wallNode.getComponent(Wall); if (this.wallComponent) { console.log('[InGameManager] 主墙体组件初始化成功'); } else { console.warn('[InGameManager] 未找到主墙体Wall组件'); } } else { console.warn('[InGameManager] 主墙体节点未通过装饰器挂载'); } // 初始化上围栏 if (this.topFenceNode) { this.topFenceComponent = this.topFenceNode.getComponent(Wall); if (this.topFenceComponent) { console.log('[InGameManager] 上围栏墙体组件初始化成功'); } else { console.warn('[InGameManager] 未找到上围栏Wall组件'); } } else { console.warn('[InGameManager] 上围栏节点未通过装饰器挂载'); } // 初始化下围栏 if (this.bottomFenceNode) { this.bottomFenceComponent = this.bottomFenceNode.getComponent(Wall); if (this.bottomFenceComponent) { console.log('[InGameManager] 下围栏墙体组件初始化成功'); } else { console.warn('[InGameManager] 未找到下围栏Wall组件'); } } else { console.warn('[InGameManager] 下围栏节点未通过装饰器挂载'); } } /** * 初始化ScreenShakeManager */ private initScreenShakeManager() { if (this.cameraNode) { ScreenShakeManager.getInstance().initialize(this.cameraNode); console.log('[InGameManager] ScreenShakeManager初始化成功'); } else { console.warn('[InGameManager] 相机节点未设置,ScreenShakeManager初始化失败'); } } /** * 获取指定波次的敌人配置 */ private getWaveEnemyConfigs(wave: number): any[] { if (!this.levelWaves || wave < 1 || wave > this.levelWaves.length) { return []; } const waveConfig = this.levelWaves[wave - 1]; return waveConfig?.enemies || []; } /** * 检查是否应该播放diban动画 */ public shouldPlayDibanAnimation(): boolean { return this.preparingNextWave && this.currentState === GameState.BLOCK_SELECTION; } /** * 技能选择完成后的处理 */ public onSkillSelectionComplete() { console.log('[InGameManager] 技能选择完成'); // 关闭技能选择UI if (this.selectSkillUI) { this.selectSkillUI.active = false; console.log('[InGameManager] 技能选择UI已关闭'); } // 恢复游戏 this.resumeGame(); // 发射技能选择结束恢复事件 EventBus.getInstance().emit(GameEvents.GAME_RESUME_SKILL_SELECTION); // 如果有等待的diban动画,现在播放diban动画 if (this.pendingBlockSelection) { console.log('[InGameManager] 技能选择完成,现在播放diban动画'); this.playDibanAnimationAfterSkill(); } } /** * 在技能选择后播放diban动画 */ public playDibanAnimationAfterSkill() { if (this.pendingBlockSelection) { console.log('[InGameManager] 技能选择完成,现在播放diban动画'); this.pendingBlockSelection = false; const totalWaves = this.levelWaves?.length || 1; if (this.currentWave < totalWaves) { this.playDibanAnimationForNextWave(); } else { console.log('[InGameManager] 最后一波结束,直接进入下一波事件以判定胜利'); // 统一在 nextWave 中进行胜利判定 this.nextWave(); } } else if (this.shouldPlayDibanAnimation()) { this.playDibanAnimationForNextWave(); } } /** * 播放下一波diban动画 */ private playDibanAnimationForNextWave() { // 如果游戏已经结束,不播放diban动画 if (this.isGameOver()) { console.warn('[InGameManager] 游戏已经结束(胜利或失败),不播放下一波diban动画!'); return; } console.log('[InGameManager] 播放diban动画'); // 生成方块选择(不显示UI) if (this.blockSelectionComponent) { this.blockSelectionComponent.generateBlockSelection(); } // 使用GameStartMove组件播放diban上滑动画和镜头下移动画 if (this.gameStartMoveComponent) { console.log('[InGameManager] 调用GameStartMove组件播放diban上滑动画'); this.gameStartMoveComponent.slideUpFromBottom(0.3); } else { console.warn('[InGameManager] GameStartMove组件未找到,无法播放diban动画'); } // 使用底板选择专用暂停事件,小球继续运动 EventBus.getInstance().emit(GameEvents.GAME_PAUSE_BLOCK_SELECTION); } /** * 处理游戏成功事件 */ private onGameSuccessEvent() { console.log('[InGameManager] 接收到游戏成功事件'); this.currentState = GameState.SUCCESS; // 游戏结束时进入暂停状态,停止所有游戏对象的行为 console.log('[InGameManager] 游戏成功,触发游戏暂停'); const eventBus = EventBus.getInstance(); eventBus.emit(GameEvents.GAME_PAUSE); } /** * 处理游戏失败事件 */ private onGameDefeatEvent() { console.log('[InGameManager] 接收到游戏失败事件'); this.currentState = GameState.DEFEAT; // 游戏结束时进入暂停状态,停止所有游戏对象的行为 console.log('[InGameManager] 游戏失败,触发游戏暂停'); const eventBus = EventBus.getInstance(); eventBus.emit(GameEvents.GAME_PAUSE); } /** * 处理游戏恢复事件 */ private onGameResumeEvent() { console.log('[InGameManager] 接收到游戏恢复事件'); } /** * 墙体被摧毁事件处理 * 墙体现在直接触发GAME_DEFEAT事件,与菜单退出处理流程一致 */ private onWallDestroyedEvent() { console.log('[InGameManager] 收到墙体被摧毁事件,墙体已直接触发GAME_DEFEAT事件'); // 不再需要调用checkGameState,因为墙体已直接触发GAME_DEFEAT事件 } /** * 处理敌人被击杀事件 */ private onEnemyKilledEvent() { // 游戏状态检查现在通过事件系统处理 if (this.isGameOver()) { console.warn('[InGameManager] 游戏已结束状态下onEnemyKilledEvent被调用!'); return; } // 如果游戏状态已经是成功或失败,不处理敌人击杀事件 if (this.currentState === GameState.SUCCESS || this.currentState === GameState.DEFEAT) { console.warn(`[InGameManager] 游戏已结束(${this.currentState}),跳过敌人击杀事件处理`); return; } this.enemiesKilled++; this.currentWaveEnemyCount++; const remaining = this.currentWaveTotalEnemies - this.currentWaveEnemyCount; console.log(`[InGameManager] 敌人被消灭,当前波剩余敌人: ${remaining}/${this.currentWaveTotalEnemies}`); // 每死一个敌人就立即增加能量 const energyBeforeIncrement = this.energyPoints; this.incrementEnergy(); // 通过事件系统更新敌人计数标签 EventBus.getInstance().emit(GameEvents.ENEMY_UPDATE_COUNT, this.currentWaveEnemyCount); // 检查能量是否已满,如果满了需要触发技能选择 const energyWillBeFull = energyBeforeIncrement + 1 >= this.energyMax; // 基于UI显示的敌人数量判断波次是否结束(Canvas-001/TopArea/EnemyNode/EnemyNumber为0) const isWaveEnd = remaining <= 0; if (isWaveEnd) { console.log(`[InGameManager] 波次结束检测: remaining=${remaining}`); console.log(`[InGameManager]当前波次: remaining=${this.currentWave}`); // 不在击杀事件中判断游戏胜利;后续胜利判定在进入下一波事件中进行 if (energyWillBeFull) { // 进入方块选择并准备下一波 this.pendingBlockSelection = true; this.preparingNextWave = true; this.currentState = GameState.BLOCK_SELECTION; } else { // 显示下一波提示(内部会在播放提示前判断是否还有后续波次) this.showNextWavePrompt(); } } else if (energyWillBeFull) { // 如果波次未结束但能量已满,设置状态为方块选择 // 注意:onEnergyFull()已在incrementEnergy()中调用,这里不需要重复调用 console.log('[InGameManager] 能量已满但波次未结束,设置方块选择状态'); this.currentState = GameState.BLOCK_SELECTION; } } /** * 增加能量值 */ private incrementEnergy() { // 获取技能等级 const energyHunterLevel = SkillManager.getInstance() ? SkillManager.getInstance().getSkillLevel('energy_hunter') : 0; const baseEnergy = 1; const bonusEnergy = SkillManager.calculateEnergyBonus ? SkillManager.calculateEnergyBonus(baseEnergy, energyHunterLevel) : baseEnergy; this.energyPoints += bonusEnergy; console.log(`[InGameManager] 能量值增加: +${bonusEnergy}, 当前: ${this.energyPoints}/${this.energyMax}`); // 检查是否达到当前能量最大值 if (this.energyPoints >= this.energyMax) { this.onEnergyFull(); // 能量满后重置为0,开始下一轮积累 this.energyPoints = 0; } this.updateEnergyBar(); } /** * 显示下一波提示 */ private showNextWavePrompt() { // 在播放下一波提示之前,先判断是否还有后续波次 const totalWaves = this.levelWaves?.length ?? -1; if (totalWaves > 0 && this.currentWave >= totalWaves) { console.log('[InGameManager] 已经没有后续波次,直接进入下一波事件以判定胜利(不播放提示与diban动画)'); this.nextWave(); return; } // 设置准备下一波的状态 this.preparingNextWave = true; this.pendingBlockSelection = true; this.currentState = GameState.BLOCK_SELECTION; console.log('[InGameManager] 设置准备下一波状态,准备播放diban动画'); // 如果当前没有技能选择UI显示,立即播放diban动画 if (!this.selectSkillUI || !this.selectSkillUI.active) { this.playDibanAnimationForNextWave(); } // 如果技能选择UI正在显示,则等待技能选择完成后再播放diban动画 // 这种情况下,pendingBlockSelection已经在onEnemyKilledEvent中设置为true } /** * 触发游戏成功 * 只负责记录游戏结束时间和发送事件,状态切换由GameEnd.ts统一处理 */ private triggerGameSuccess() { // 防止重复触发游戏成功 if (this.currentState === GameState.SUCCESS || this.currentState === GameState.DEFEAT) { console.log('[InGameManager] 游戏已结束,跳过重复的成功触发'); return; } // 记录游戏结束时间 this.gameEndTime = Date.now(); // 触发游戏结束状态事件 EventBus.getInstance().emit(GameEvents.ENTER_GAME_END_STATE, { result: 'success' }); console.log('[InGameManager] 游戏成功,发送GAME_SUCCESS事件,状态切换由GameEnd.ts处理'); EventBus.getInstance().emit(GameEvents.GAME_SUCCESS); } /** * 获取游戏持续时间 */ public getGameDuration(): number { const endTime = this.gameEndTime || Date.now(); return Math.max(0, endTime - this.gameStartTime); } /** * 获取当前游戏状态 */ public getCurrentState(): GameState { return this.currentState; } /** * 设置游戏状态 */ public setCurrentState(state: GameState) { this.currentState = state; // 当游戏状态变为PLAYING时,更新能量条显示 if (state === GameState.PLAYING) { this.updateEnergyBar(); } } /** * 初始化UI节点 */ private initUINodes() { // 初始化能量条 if (this.energyBarNode) { this.energyBar = this.energyBarNode.getComponent(ProgressBar); if (this.energyBar) { console.log('[InGameManager] 能量条组件初始化成功'); // 不在初始化阶段更新能量条,等待游戏状态变为PLAYING后再更新 } else { console.error('[InGameManager] 能量条节点存在但ProgressBar组件未找到'); } } else { console.error('[InGameManager] 能量条节点未通过装饰器挂载,请在Inspector中拖拽EnergyBar节点'); } // 初始化技能选择UI if (this.selectSkillUINode) { this.selectSkillUI = this.selectSkillUINode; console.log('[InGameManager] 技能选择UI节点初始化成功'); } else { console.error('[InGameManager] 技能选择UI节点未通过装饰器挂载,请在Inspector中拖拽SelectSkillUI节点'); } // 初始化背景管理器 if (this.backgroundManagerNode) { this.backgroundManager = this.backgroundManagerNode.getComponent(BackgroundManager); if (this.backgroundManager) { console.log('[InGameManager] 背景管理器组件初始化成功'); } else { console.error('[InGameManager] 背景管理器节点存在但BackgroundManager组件未找到'); } } else { console.error('[InGameManager] 背景管理器节点未通过装饰器挂载,请在Inspector中拖拽BackgroundManager节点'); } // 初始化地面燃烧区域管理器 if (this.groundBurnAreaManagerNode) { this.groundBurnAreaManager = this.groundBurnAreaManagerNode.getComponent(GroundBurnAreaManager); if (this.groundBurnAreaManager) { console.log('[InGameManager] 地面燃烧区域管理器组件初始化成功'); } else { console.error('[InGameManager] 地面燃烧区域管理器节点存在但GroundBurnAreaManager组件未找到'); } } else { console.error('[InGameManager] 地面燃烧区域管理器节点未通过装饰器挂载,请在Inspector中拖拽GroundBurnAreaManager节点'); } } /** * 更新能量条显示 */ private updateEnergyBar() { // 只有在游戏状态为PLAYING时才更新能量条,避免初始化阶段的报错 if (this.currentState !== GameState.PLAYING) { return; } if (this.energyBar && this.energyMax > 0) { const progress = this.energyPoints / this.energyMax; this.energyBar.progress = Math.min(progress, 1.0); console.log(`[InGameManager] 能量条更新: ${this.energyPoints}/${this.energyMax} (${Math.round(progress * 100)}%)`); } else { console.warn('[InGameManager] 能量条组件未初始化或energyMax未设置,无法更新显示'); } } /** * 能量满时的处理 */ private onEnergyFull() { console.log('[InGameManager] 能量已满,开始升级处理'); // 升级能量条 this.upgradeEnergySystem(); // 显示技能选择UI this.showSkillSelection(); } /** * 升级能量系统 */ private upgradeEnergySystem() { // 增加升级次数 this.energyUpgradeCount++; // 更新能量最大值 // energyMaxUpgrades数组索引0是初始值,索引1是第1次升级后的值,以此类推 if (this.energyUpgradeCount < this.energyMaxUpgrades.length) { const newMaxEnergy = this.energyMaxUpgrades[this.energyUpgradeCount]; this.energyMax = newMaxEnergy; console.log(`[InGameManager] 能量条升级 ${this.energyUpgradeCount} 次,新的最大值: ${this.energyMax}`); } else { // 超出配置次数,按照上一次的值+1递增 this.energyMax = this.energyMax + 1; console.log(`[InGameManager] 能量条升级超出配置次数,使用递增模式,新的最大值: ${this.energyMax}`); } // 立即更新能量条显示,确保新的最大值生效 this.updateEnergyBar(); } /** * 显示技能选择UI */ private showSkillSelection() { if (this.selectSkillUI) { this.selectSkillUI.active = true; // 使用技能选择专用暂停事件,所有小球停止运动 EventBus.getInstance().emit(GameEvents.GAME_PAUSE_SKILL_SELECTION); // 注意:不调用StartGame.resetEnergy(),因为那会重置整个能量系统包括最大值 // 能量点数已在onEnergyFull()中重置为0 } } /** * 恢复游戏 */ private resumeGame() { console.log('[InGameManager] 恢复游戏'); EventBus.getInstance().emit(GameEvents.GAME_RESUME); } /** * 检查游戏是否结束 */ private isGameOver(): boolean { let gameOver = false; EventBus.getInstance().emit(GameEvents.GAME_CHECK_OVER, (isOver: boolean) => { gameOver = isOver; }); return gameOver; } /** * 设置当前波次 */ public setCurrentWave(wave: number, enemyCount: number = 0) { this.currentWave = wave; this.currentWaveEnemyCount = 0; // 重置当前击杀数 this.currentWaveTotalEnemies = enemyCount; // 设置该波次总敌人数 const totalWaves = this.levelWaves?.length || 1; // 获取波次敌人配置 const waveEnemyConfigs = this.getWaveEnemyConfigs(wave); // 获取当前波次的血量系数 let healthMultiplier = 1.0; if (this.levelWaves && this.levelWaves.length > 0) { const waveIndex = wave - 1; // 波次从1开始,数组从0开始 if (waveIndex >= 0 && waveIndex < this.levelWaves.length) { const waveData = this.levelWaves[waveIndex]; if (waveData && typeof waveData.healthMultiplier === 'number') { healthMultiplier = waveData.healthMultiplier; } } } // 通过事件系统启动波次 EventBus.getInstance().emit(GameEvents.ENEMY_START_WAVE, { wave: wave, totalWaves: totalWaves, enemyCount: enemyCount, waveEnemyConfigs: waveEnemyConfigs, healthMultiplier: healthMultiplier }); } /** * 更新当前波次敌人数量 */ public updateCurrentWaveEnemyCount(count: number) { this.currentWaveEnemyCount = count; } /** * 获取当前波次 */ public getCurrentWave(): number { return this.currentWave; } /** * 获取当前波次敌人数量 */ public getCurrentWaveEnemyCount(): number { return this.currentWaveEnemyCount; } /** * 获取当前波次总敌人数量 */ public getCurrentWaveTotalEnemies(): number { return this.currentWaveTotalEnemies; } /** * 进入下一波 */ public nextWave() { const totalWaves = this.levelWaves?.length ?? -1; // 仅当总波次有效且没有下一波时触发胜利 if (totalWaves > 0 && this.currentWave >= totalWaves) { console.log('[InGameManager] 没有下一波,触发游戏胜利'); this.triggerGameSuccess(); return; } this.currentWave++; // 根据关卡配置获取下一波敌人数 let enemyTotal = 0; if (this.levelWaves && this.levelWaves.length >= this.currentWave) { const waveCfg = this.levelWaves[this.currentWave - 1]; if (waveCfg && waveCfg.enemies) { enemyTotal = waveCfg.enemies.reduce((t: number, g: any) => t + (g.count || 0), 0); } } this.setCurrentWave(this.currentWave, enemyTotal); } /** * 获取当前能量值 */ public getCurrentEnergy(): number { return this.energyPoints; } /** * 获取最大能量值 */ public getMaxEnergy(): number { return this.energyMax; } /** * 获取墙体健康度(返回主墙体健康度) */ public getWallHealth(): number { if (this.wallComponent) { return this.wallComponent.getCurrentHealth(); } return 0; } /** * 获取所有墙体的健康度 */ public getAllWallsHealth(): { main: number; topFence: number; bottomFence: number } { return { main: this.wallComponent ? this.wallComponent.getCurrentHealth() : 0, topFence: this.topFenceComponent ? this.topFenceComponent.getCurrentHealth() : 0, bottomFence: this.bottomFenceComponent ? this.bottomFenceComponent.getCurrentHealth() : 0 }; } /** * 根据等级获取墙体健康度 */ public getWallHealthByLevel(level: number): number { if (this.wallComponent) { return this.wallComponent.getWallHealthByLevel(level); } return 100; } /** * 获取当前墙体等级(返回主墙体等级) */ public getCurrentWallLevel(): number { if (this.wallComponent) { return this.wallComponent.getCurrentWallLevel(); } return 1; } /** * 获取当前墙体健康度(返回主墙体健康度) */ public getCurrentWallHealth(): number { if (this.wallComponent) { return this.wallComponent.getCurrentHealth(); } return 100; } /** * 获取所有墙体的等级 */ public getAllWallsLevel(): { main: number; topFence: number; bottomFence: number } { return { main: this.wallComponent ? this.wallComponent.getCurrentWallLevel() : 1, topFence: this.topFenceComponent ? this.topFenceComponent.getCurrentWallLevel() : 1, bottomFence: this.bottomFenceComponent ? this.bottomFenceComponent.getCurrentWallLevel() : 1 }; } /** * 处理确认操作(方块选择确认) */ public handleConfirmAction() { console.log('[InGameManager] 处理方块选择确认操作'); // 如果是在准备下一波的状态,需要先切换到下一波 if (this.preparingNextWave) { console.log('[InGameManager] 检测到准备下一波状态,切换到下一波'); this.nextWave(); // 重置状态 this.preparingNextWave = false; this.pendingBlockSelection = false; this.currentState = GameState.PLAYING; } // 触发进入游玩状态事件 EventBus.getInstance().emit(GameEvents.ENTER_PLAYING_STATE); // 注意:不再发送GAME_START事件,避免重复触发游戏启动流程 // 游戏启动流程已在用户点击战斗按钮时完成,这里只需要启动游戏逻辑 // 通过事件系统启动球的移动 EventBus.getInstance().emit(GameEvents.BALL_START); console.log('[InGameManager] 发送BALL_START事件,球已启动'); // 通过事件系统开始当前波次的敌人生成 EventBus.getInstance().emit(GameEvents.ENEMY_START_GAME); EventBus.getInstance().emit(GameEvents.ENEMY_SHOW_START_WAVE_PROMPT); console.log(`[InGameManager] 波次 ${this.currentWave} 敌人生成已启动`); } /** * 重置能量值(供StartGame调用) */ public resetEnergyValue() { this.energyPoints = 0; this.updateEnergyBar(); console.log('[InGameManager] 能量值重置完成'); } /** * 重置波次信息(供StartGame调用) */ public resetWaveInfo() { this.currentWave = 1; this.currentWaveEnemyCount = 0; this.currentWaveTotalEnemies = 0; this.enemiesKilled = 0; this.totalEnemiesSpawned = 0; this.levelTotalEnemies = 0; console.log('[InGameManager] 波次信息重置完成'); } /** * 重置能量系统(供StartGame调用) * 注意:只在游戏真正重新开始时重置升级状态,技能选择后不应重置升级状态 */ public resetEnergySystem() { this.energyPoints = 0; // 只有在游戏状态不是BLOCK_SELECTION时才重置升级状态 // 这样可以避免技能选择后重置已获得的能量升级 if (this.currentState !== GameState.BLOCK_SELECTION) { this.energyUpgradeCount = 0; // 重置energyMax到初始值(energyMaxUpgrades数组的第一个值) if (this.energyMaxUpgrades && this.energyMaxUpgrades.length > 0) { this.energyMax = this.energyMaxUpgrades[0]; } console.log('[InGameManager] 能量系统完全重置(包括升级状态)'); } else { console.log('[InGameManager] 技能选择状态下,仅重置能量点数,保持升级状态'); } this.updateEnergyBar(); console.log('[InGameManager] 能量系统重置完成'); } /** * 清理游戏数据,为返回主页面做准备 * 当游戏胜利或失败返回主页面时调用 */ private cleanupGameDataForMainMenu() { console.log('[InGameManager] 开始清理游戏数据,准备返回主页面'); const eventBus = EventBus.getInstance(); // 1. 清空场上的所有游戏对象 console.log('[InGameManager] 清空场上敌人、方块、球'); eventBus.emit(GameEvents.CLEAR_ALL_ENEMIES); // 清空所有敌人 eventBus.emit(GameEvents.CLEAR_ALL_BULLETS); // 清空所有子弹 eventBus.emit(GameEvents.CLEAR_ALL_GAME_OBJECTS); // 清空其他游戏对象 // 2. 重置能量系统 console.log('[InGameManager] 重置能量系统'); this.energyPoints = 0; this.updateEnergyBar(); // 3. 清空技能选择数据(重置临时技能状态) console.log('[InGameManager] 清空技能选择数据'); const skillManager = SkillManager.getInstance(); if (skillManager) { skillManager.resetAllSkillLevels(); } // 4. 重置关卡数据和游戏状态 console.log('[InGameManager] 重置关卡数据和游戏状态'); this.currentWave = 1; this.currentWaveEnemyCount = 0; this.currentWaveTotalEnemies = 0; this.enemiesKilled = 0; this.totalEnemiesSpawned = 0; this.levelTotalEnemies = 0; this.levelWaves = []; this.gameStarted = false; this.enemySpawningStarted = false; this.preparingNextWave = false; this.pendingSkillSelection = false; this.pendingBlockSelection = false; this.shouldShowNextWavePrompt = false; // 5. 重置UI状态 console.log('[InGameManager] 重置UI状态'); if (this.selectSkillUI) { this.selectSkillUI.active = false; } // 6. 清理会话数据(局内金币等临时数据) console.log('[InGameManager] 清理会话数据'); if (LevelSessionManager.inst) { LevelSessionManager.inst.clear(); // 清空局内金币等临时数据 } // 7. 通过事件系统通知其他组件进行清理 eventBus.emit(GameEvents.RESET_BALL_CONTROLLER); // 重置球控制器 eventBus.emit(GameEvents.RESET_BLOCK_MANAGER); // 重置方块管理器 eventBus.emit(GameEvents.RESET_BLOCK_SELECTION); // 重置方块选择 eventBus.emit(GameEvents.RESET_ENEMY_CONTROLLER); // 重置敌人控制器 eventBus.emit(GameEvents.RESET_WALL_HEALTH); // 重置墙体血量 eventBus.emit(GameEvents.RESET_UI_STATES); // 重置UI状态 // 8. 重置镜头位置 console.log('[InGameManager] 重置镜头位置'); if (this.gameStartMoveComponent) { this.gameStartMoveComponent.resetCameraToOriginalPositionImmediate(); } else { console.warn('[InGameManager] GameStartMove组件未找到,无法重置镜头位置'); } // 9. 发送游戏结束事件,确保游戏状态正确转换 console.log('[InGameManager] 发送游戏结束事件'); eventBus.emit('GAME_END'); // 10. 重置游戏状态为初始状态 this.currentState = GameState.PLAYING; // 11. 重置游戏结束时间,确保下次游戏状态检查正常 this.gameEndTime = 0; console.log('[InGameManager] 游戏数据清理完成,可以安全返回主页面'); } /** * 重置游戏状态(供StartGame调用) */ public resetGameStates() { this.currentState = GameState.PLAYING; this.gameStarted = false; this.enemySpawningStarted = false; this.preparingNextWave = false; this.pendingSkillSelection = false; this.pendingBlockSelection = false; this.shouldShowNextWavePrompt = false; this.gameStartTime = 0; this.gameEndTime = 0; console.log('[InGameManager] 游戏状态重置完成'); } // resetGameRecord方法已被移除,避免与cleanupGameDataForMainMenu重复 // 所有清理逻辑已统一在cleanupGameDataForMainMenu中处理 /** * 手动触发游戏数据清理(供外部调用) * 可以在返回主菜单按钮点击时调用 */ public triggerGameDataCleanup() { this.cleanupGameDataForMainMenu(); } /** * 应用关卡配置 */ public async applyLevelConfig(levelConfig: any) { console.log('[InGameManager] 应用关卡配置'); // 应用能量配置 - 现在从energyMaxUpgrades数组获取初始值 let initialEnergyMax = 5; // 默认值 // 先读取energyMaxUpgrades配置以获取初始能量最大值 if (levelConfig.levelSettings && levelConfig.levelSettings.energyMaxUpgrades && Array.isArray(levelConfig.levelSettings.energyMaxUpgrades) && levelConfig.levelSettings.energyMaxUpgrades.length > 0) { initialEnergyMax = levelConfig.levelSettings.energyMaxUpgrades[0]; console.log(`[InGameManager] 从energyMaxUpgrades获取初始能量配置: ${initialEnergyMax}`); } else { console.warn('[InGameManager] 警告:关卡配置中缺少 energyMaxUpgrades 设置,使用默认值!'); } this.energyMax = initialEnergyMax; this.updateEnergyBar(); // 应用新的能量条升级配置 if (levelConfig.levelSettings) { // 读取能量条升级后最大值配置 if (levelConfig.levelSettings.energyMaxUpgrades && Array.isArray(levelConfig.levelSettings.energyMaxUpgrades)) { this.energyMaxUpgrades = [...levelConfig.levelSettings.energyMaxUpgrades]; console.log(`[InGameManager] 应用能量条升级配置: ${this.energyMaxUpgrades.length}个配置`); } else { // 默认升级配置(基于初始最大值递增) this.energyMaxUpgrades = []; for (let i = 0; i < 20; i++) { this.energyMaxUpgrades.push(this.energyMax + i + 1); } console.log('[InGameManager] 使用默认能量条升级配置'); } this.energyUpgradeCount = 0; console.log('[InGameManager] 初始化能量条升级系统'); } // 如果有武器配置,应用武器 if (levelConfig.weapons && Array.isArray(levelConfig.weapons)) { console.log('[InGameManager] 应用武器配置'); // TODO: 应用武器配置逻辑 } // 如果有波次配置,设置敌人波次 if (levelConfig.waves && Array.isArray(levelConfig.waves)) { this.levelWaves = levelConfig.waves; this.currentWave = 1; // 计算本关卡总敌人数 this.levelTotalEnemies = 0; for (const wave of this.levelWaves) { for (const enemy of wave.enemies || []) { this.levelTotalEnemies += enemy.count || 0; } } console.log(`[InGameManager] 应用波次配置: ${this.levelWaves.length}波,总敌人数: ${this.levelTotalEnemies}`); // 通过事件系统通知 EnemyController 初始化第一波数据及 UI const firstWaveEnemies = this.levelWaves.length > 0 && this.levelWaves[0].enemies ? this.levelWaves[0].enemies.reduce((t: number, g: any) => t + (g.count || 0), 0) : 0; // 通过事件系统调用setCurrentWave this.setCurrentWave(1, firstWaveEnemies); } // 应用背景图片配置 if (this.backgroundManager && levelConfig.backgroundImage) { // 转换路径格式:从 "images/LevelBackground/BG1" 转换为 "LevelBackground/BG1" const bundlePath = levelConfig.backgroundImage.replace('images/', ''); await this.backgroundManager.setBackground(bundlePath); console.log(`[InGameManager] 应用背景配置: ${levelConfig.backgroundImage}`); } else if (this.backgroundManager) { // 如果没有指定背景图片,使用默认背景 await this.backgroundManager.setBackground('LevelBackground/BG1'); console.log('[InGameManager] 使用默认背景: LevelBackground/BG1'); } // 上报 $StartSection 事件 try { const currentLevel = SaveDataManager.getInstance().getCurrentLevel(); const userMoney = SaveDataManager.getInstance().getMoney(); const levelConfigManager = LevelConfigManager.getInstance(); const levelName = levelConfigManager ? levelConfigManager.getLevelName(currentLevel) : `关卡 ${currentLevel}`; const startSectionProperties = { $section_id: currentLevel, $section_name: levelName, $section_type: 'level', total_waves: this.levelWaves.length, total_enemies: this.levelTotalEnemies, energy_max: this.energyMax, user_level: currentLevel, user_money: userMoney, background_image: levelConfig.backgroundImage || 'LevelBackground/BG1' }; AnalyticsManager.getInstance().trackStartSection(startSectionProperties); console.log('[InGameManager] $StartSection 事件已上报', startSectionProperties); } catch (error) { console.error('[InGameManager] $StartSection 事件上报失败:', error); } } /** * 同步播放战斗音乐(立即执行,不等待异步操作) */ private playBattleMusicSync() { try { console.log('[InGameManager] 立即播放战斗音乐'); // 先停止当前播放的音乐 Audio.stopMusic(); // 设置音乐音量 Audio.setMusicVolume(0.8); // 播放战斗音乐(循环播放)- 不等待异步操作 Audio.updateBGMByTopUI(); console.log('[InGameManager] 战斗音乐播放指令已发送'); } catch (error) { console.error('[InGameManager] 播放战斗音乐失败:', error); } } onDestroy() { const eventBus = EventBus.getInstance(); eventBus.off(GameEvents.GAME_SUCCESS, this.onGameSuccessEvent, this); eventBus.off(GameEvents.GAME_DEFEAT, this.onGameDefeatEvent, this); eventBus.off(GameEvents.GAME_RESUME, this.onGameResumeEvent, this); eventBus.off(GameEvents.GAME_RESUME_SKILL_SELECTION, this.onGameResumeEvent, this); eventBus.off(GameEvents.GAME_RESUME_BLOCK_SELECTION, this.onGameResumeEvent, this); eventBus.off('ENEMY_KILLED', this.onEnemyKilledEvent, this); eventBus.off(GameEvents.RESET_ENERGY_SYSTEM, this.resetEnergySystem, this); eventBus.off(GameEvents.WALL_DESTROYED, this.onWallDestroyedEvent, this); } }