// MainUIController.ts import { _decorator, Component, Node, Button, Label } from 'cc'; import { SaveDataManager } from '../../LevelSystem/SaveDataManager'; import { GameManager, AppState } from '../../LevelSystem/GameManager'; import { GameState } from '../../LevelSystem/IN_game'; import { GameStartMove } from '../../Animations/GameStartMove'; import { TopBarController } from '../TopBarController'; import { MoneyAni } from '../../Animations/MoneyAni'; import EventBus, { GameEvents } from '../../Core/EventBus'; const { ccclass, property } = _decorator; @ccclass('MainUIController') export class MainUIController extends Component { /* 奖励节点 */ @property(Node) rewardMoneyNode: Node = null; // 左金币奖励 @property(Node) rewardDiamondNode: Node = null; // 右钻石奖励 @property(Label) levelNumberLabel: Label = null; // 第 X 关文本 /* 升级 */ @property(Button) upgradeBtn: Button = null; // 升级按钮 @property(Node) upgradeCostLabel: Node = null; // 消耗金币数字 @property(Node) upgradeHpLabel: Node = null; // "100>>1000" /* 主功能按钮 */ @property(Node) battleBtn: Node = null; // 战斗 // 底栏按钮由 NavBarController 统一管理,这里不再需要引用 @property(Node) topArea: Node = null; // Canvas-001/TopArea /* UI节点引用 - 替换find查找 */ @property(Node) mainUI: Node = null; // Canvas/MainUI @property(Node) gameUI: Node = null; // Canvas/GameLevelUI @property(Node) gameManagerNode: Node = null; // Canvas/GameLevelUI/GameManager @property(Node) navBarNode: Node = null; // Canvas/NavBar @property(Node) topBarNode: Node = null; // Canvas/TopBar @property(Node) cameraNode: Node = null; // Canvas/Camera /* 奖励动画系统 */ @property(Node) moneyAniNode: Node = null; // MoneyAni节点 private sdm: SaveDataManager = null; onLoad () { this.sdm = SaveDataManager.getInstance(); this.sdm.initialize(); this.bindButtons(); this.refreshAll(); // TopArea 默认隐藏,在点击战斗后再显示 if (this.topArea) this.topArea.active = false; } /* 绑定按钮事件 */ private bindButtons () { this.upgradeBtn?.node.on(Button.EventType.CLICK, this.upgradeWallHp, this); this.battleBtn?.on(Button.EventType.CLICK, this.onBattle, this); } /* ================= 业务逻辑 ================= */ private upgradeWallHp () { // 直接使用SaveDataManager进行墙体升级 if (!this.sdm.canUpgradeWall()) { console.log('无法升级墙体:条件不满足'); return; } const cost = this.sdm.getWallUpgradeCost(); if (!this.sdm.spendCoins(cost)) { console.log('无法升级墙体:金币不足'); return; } if (!this.sdm.upgradeWallLevel()) { console.log('墙体升级失败'); return; } console.log('墙体升级成功'); // 刷新所有UI显示 this.refreshAll(); // 通过事件系统通知UI更新 EventBus.getInstance().emit(GameEvents.CURRENCY_CHANGED); } private onBattle () { // 显示 TopArea(拖拽引用),避免使用 find() if (this.topArea) this.topArea.active = true; // 若上一关已完成则自动+1 const lvl = this.sdm.getCurrentLevel(); if (this.sdm.isLevelCompleted(lvl)) { const pd = this.sdm.getPlayerData(); pd.currentLevel = lvl + 1; this.sdm.savePlayerData(); } this.refreshLevelNumber(); // 切场景 UI - 使用装饰器引用 if (this.mainUI) this.mainUI.active = false; if (this.gameUI) this.gameUI.active = true; const gm = this.gameManagerNode?.getComponent(GameManager); // 设置应用状态为游戏中(会自动隐藏TopBar和NavBar) gm?.setAppState(AppState.IN_GAME); // 统一使用StartGame启动游戏流程 const eventBus = EventBus.getInstance(); eventBus.emit(GameEvents.GAME_START); gm?.loadCurrentLevelConfig(); // 镜头下移动画现在已集成到StartGame流程中的slideUpFromBottom方法里 } /* ================= 刷新 ================= */ private refreshLevelNumber(){ if (this.levelNumberLabel) this.levelNumberLabel.string = `第 ${this.sdm.getCurrentLevel()} 关`; } private refreshAll(){ this.refreshLevelNumber(); this.refreshUpgradeInfo(); this.refreshRewardDisplay(); } /** 刷新奖励显示 - 从JSON配置读取 */ private async refreshRewardDisplay() { const currentLevel = this.sdm.getCurrentLevel(); try { // 从SaveDataManager获取关卡奖励配置 const rewards = await this.sdm.getLevelRewardsFromConfig(currentLevel); if (rewards) { // 更新金币奖励显示 if (this.rewardMoneyNode) { const coinLabel = this.rewardMoneyNode.getComponent(Label) || this.rewardMoneyNode.getComponentInChildren(Label); if (coinLabel) { coinLabel.string = rewards.coins.toString(); } } // 更新钻石奖励显示 if (this.rewardDiamondNode) { const diamondLabel = this.rewardDiamondNode.getComponent(Label) || this.rewardDiamondNode.getComponentInChildren(Label); if (diamondLabel) { diamondLabel.string = rewards.diamonds.toString(); } } } else { console.warn(`无法获取关卡${currentLevel}的奖励配置,使用默认值`); // 使用默认奖励值 this.setDefaultRewards(); } } catch (error) { console.error('刷新奖励显示时出错:', error); this.setDefaultRewards(); } } /** 设置默认奖励值 */ private setDefaultRewards() { // 金币奖励默认值 if (this.rewardMoneyNode) { const coinLabel = this.rewardMoneyNode.getComponent(Label) || this.rewardMoneyNode.getComponentInChildren(Label); if (coinLabel) { coinLabel.string = '50'; } } // 钻石奖励默认值 if (this.rewardDiamondNode) { const diamondLabel = this.rewardDiamondNode.getComponent(Label) || this.rewardDiamondNode.getComponentInChildren(Label); if (diamondLabel) { diamondLabel.string = '5'; } } } /** 刷新升级信息显示 */ private refreshUpgradeInfo () { const costLbl = this.upgradeCostLabel?.getComponent(Label); const hpLbl = this.upgradeHpLabel?.getComponent(Label); if (!costLbl || !hpLbl) return; // 显示升级费用 const cost = this.sdm.getWallUpgradeCost(); costLbl.string = cost.toString(); // 显示当前和下一级血量 const currentLevel = this.sdm.getWallLevel(); const currentHp = this.sdm.getPlayerData()?.wallBaseHealth || 100; // 计算下一级血量 const wallHpMap: Record = { 1: 100, 2: 1000, 3: 1200, 4: 1500, 5: 2000 }; const nextHp = wallHpMap[currentLevel + 1] || (100 + currentLevel * 200); hpLbl.string = `${currentHp}>>${nextHp}`; // 根据是否可以升级来设置按钮状态 if (this.upgradeBtn) { this.upgradeBtn.interactable = this.sdm.canUpgradeWall(); } } // 供外部(如 GameManager)调用的公共刷新接口 public updateUI (): void { this.refreshAll(); // 通过事件系统通知UI更新 EventBus.getInstance().emit(GameEvents.CURRENCY_CHANGED); } /** * 游戏失败或成功返回MainUI后的UI状态管理 * 隐藏Canvas-001并显示Canvas/TopBar和Canvas/NavBar */ public onReturnToMainUI(): void { console.log('MainUIController.onReturnToMainUI 开始执行'); // 设置应用状态为主菜单 const gm = this.gameManagerNode?.getComponent(GameManager); gm?.setAppState(AppState.MAIN_MENU); // 隐藏 TopArea (Canvas-001) if (this.topArea) { this.topArea.active = false; console.log('TopArea (Canvas-001) 已隐藏'); } // 显示主UI if (this.mainUI) { this.mainUI.active = true; console.log('MainUI 已显示'); } // 隐藏游戏UI if (this.gameUI) { this.gameUI.active = false; console.log('GameUI 已隐藏'); } // 显示顶部钱币栏 TopBar if (this.topBarNode) { this.topBarNode.active = true; console.log('TopBar 已显示'); } // 显示底部导航栏 NavBar if (this.navBarNode) { this.navBarNode.active = true; console.log('NavBar 已显示'); } // 刷新UI显示 this.refreshAll(); // 通过事件系统通知UI更新 EventBus.getInstance().emit(GameEvents.CURRENCY_CHANGED); console.log('MainUIController.onReturnToMainUI 执行完成'); } /** * 游戏成功返回MainUI并播放奖励动画 */ public onReturnToMainUIWithReward(): void { console.log('MainUIController.onReturnToMainUIWithReward 开始执行'); // 先执行基本的UI状态管理 this.onReturnToMainUI(); // 延迟播放奖励动画,确保UI已经完全显示 this.scheduleOnce(() => { this.playRewardAnimation(); }, 0.5); } /** * 播放奖励动画 */ private async playRewardAnimation(): Promise { console.log('MainUIController.playRewardAnimation 开始播放奖励动画'); const currentLevel = this.sdm.getCurrentLevel(); try { // 获取游戏管理器以判断游戏状态 const gameManager = this.gameManagerNode?.getComponent(GameManager); const currentGameState = gameManager?.getCurrentGameState(); const isGameSuccess = currentGameState === GameState.SUCCESS; // 使用游戏内状态枚举进行比较 let rewards; if (isGameSuccess) { // 游戏成功,获取完整奖励 console.log('游戏成功,获取完整奖励'); rewards = this.sdm.getLastRewards(); } else { // 游戏失败,直接获取已经计算好的失败奖励 console.log('游戏失败,获取已计算的部分奖励'); rewards = this.sdm.getLastRewards(); // 记录波数完成情况用于调试 const currentWave = gameManager?.getCurrentWave() || 0; const inGameManager = gameManager?.getInGameManager(); const totalWaves = inGameManager?.levelWaves?.length || 1; const completedWaves = Math.max(0, currentWave - 1); console.log(`波数完成情况: ${completedWaves}/${totalWaves} = ${(completedWaves / totalWaves * 100).toFixed(1)}%`); console.log('计算出的失败奖励:', rewards); } if (rewards && (rewards.coins > 0 || rewards.diamonds > 0)) { // 使用MoneyAni播放奖励动画 if (this.moneyAniNode) { const moneyAni = this.moneyAniNode.getComponent(MoneyAni); if (moneyAni) { moneyAni.playRewardAnimation(rewards.coins, rewards.diamonds, () => { console.log('奖励动画播放完成'); }); } else { console.error('MoneyAni组件未找到'); // 使用静态方法作为备选 MoneyAni.playReward(rewards.coins, rewards.diamonds); } } else { console.warn('MoneyAni节点未设置,使用静态方法播放动画'); MoneyAni.playReward(rewards.coins, rewards.diamonds); } } else { console.log('当前关卡没有奖励或奖励为0'); } } catch (error) { console.error('播放奖励动画时出错:', error); // 使用默认奖励 MoneyAni.playReward(25, 2); } } /* =============== Util =============== */ private format(n:number){ return n>=1000000? (n/1e6).toFixed(1)+'M' : n>=1000? (n/1e3).toFixed(1)+'K' : n.toString(); } }