MainUIController.ts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // MainUIController.ts
  2. import { _decorator, Component, Node, Button, Label, find } from 'cc';
  3. import { SaveDataManager } from './SaveDataManager';
  4. import { GameManager } from './GameManager';
  5. import { GameStartMove } from '../Animations/GameStartMove';
  6. const { ccclass, property } = _decorator;
  7. @ccclass('MainUIController')
  8. export class MainUIController extends Component {
  9. /* 顶部资源 & 关卡 */
  10. @property(Node) moneyAddBtn: Node = null; // 绿色 +
  11. @property(Node) diamondAddBtn: Node = null; // 紫色 +
  12. @property(Node) moneyLabel: Node = null; // 金币数字
  13. @property(Node) diamondLabel: Node = null; // 钻石数字
  14. @property(Label) levelNumberLabel: Label = null; // 第 X 关文本
  15. /* 奖励节点 */
  16. @property(Node) rewardMoneyNode: Node = null; // 左金币奖励
  17. @property(Node) rewardDiamondNode: Node = null; // 右钻石奖励
  18. /* 升级 */
  19. @property(Button) upgradeBtn: Button = null; // 升级按钮
  20. @property(Node) upgradeCostLabel: Node = null; // 消耗金币数字
  21. @property(Node) upgradeHpLabel: Node = null; // "105>>1000"
  22. /* 主功能按钮 */
  23. @property(Node) battleBtn: Node = null; // 战斗
  24. @property(Node) shopBtn: Node = null; // 商店
  25. @property(Node) navUpgradeBtn: Node = null; // 底栏 UPGRADE
  26. @property(Node) navBattleBtn: Node = null; // 底栏 BATTLE
  27. @property(Node) navSkillBtn: Node = null; // 底栏 SKILL
  28. @property(Node) topArea: Node = null; // Canvas-001/TopArea
  29. private sdm: SaveDataManager = null;
  30. onLoad () {
  31. this.sdm = SaveDataManager.getInstance();
  32. this.sdm.initialize();
  33. this.bindButtons();
  34. this.refreshAll();
  35. // TopArea 默认隐藏,在点击战斗后再显示
  36. if (this.topArea) this.topArea.active = false;
  37. }
  38. /* 绑定按钮事件 */
  39. private bindButtons () {
  40. this.moneyAddBtn?.on(Button.EventType.CLICK, () => this.addCoins(100), this);
  41. this.diamondAddBtn?.on(Button.EventType.CLICK, () => this.addDiamonds(20), this);
  42. this.rewardMoneyNode?.on(Node.EventType.TOUCH_END, () => this.takeRewardCoins(), this);
  43. this.rewardDiamondNode?.on(Node.EventType.TOUCH_END, () => this.takeRewardDiamonds(), this);
  44. this.upgradeBtn?.node.on(Button.EventType.CLICK, this.upgradeWallHp, this);
  45. this.battleBtn?.on(Button.EventType.CLICK, this.onBattle, this);
  46. this.shopBtn?.on(Button.EventType.CLICK, this.onShop, this);
  47. // 底栏按钮暂只打印
  48. this.navUpgradeBtn?.on(Button.EventType.CLICK, () => console.log('底栏 UPGRADE'), this);
  49. this.navBattleBtn?.on(Button.EventType.CLICK, () => console.log('底栏 BATTLE'), this);
  50. this.navSkillBtn?.on(Button.EventType.CLICK, () => console.log('底栏 SKILL'), this);
  51. }
  52. /* ================= 业务逻辑 ================= */
  53. private addCoins (v:number) { this.sdm.addCoins(v, 'ad'); this.refreshCurrency(); }
  54. private addDiamonds (v:number){ this.sdm.addDiamonds(v,'ad'); this.refreshCurrency(); }
  55. private takeRewardCoins () {
  56. const lbl = this.rewardMoneyNode?.getComponent(Label) || this.rewardMoneyNode?.getComponentInChildren(Label);
  57. if (!lbl) return;
  58. const amt = parseInt(lbl.string||'0');
  59. if (amt>0) { this.addCoins(amt); this.rewardMoneyNode.active = false; }
  60. }
  61. private takeRewardDiamonds () {
  62. const lbl = this.rewardDiamondNode?.getComponent(Label) || this.rewardDiamondNode?.getComponentInChildren(Label);
  63. if (!lbl) return;
  64. const amt = parseInt(lbl.string||'0');
  65. if (amt>0) { this.addDiamonds(amt); this.rewardDiamondNode.active = false; }
  66. }
  67. private upgradeWallHp () {
  68. const costLbl = this.upgradeCostLabel?.getComponent(Label);
  69. if (!costLbl) return;
  70. const cost = parseInt(costLbl.string || '0');
  71. if (!this.sdm.spendCoins(cost)) return; // 金币不足
  72. // 升级墙体
  73. const gmNode = find('Canvas/GameLevelUI/GameManager');
  74. const gm = gmNode?.getComponent(GameManager);
  75. if (!gm) return;
  76. const info = gm.upgradeWallLevel?.();
  77. if (!info) return;
  78. // 更新显示
  79. const hpLbl = this.upgradeHpLabel?.getComponent(Label);
  80. if (hpLbl) {
  81. hpLbl.string = `${info.currentHp}>>${info.nextHp}`;
  82. }
  83. this.refreshCurrency();
  84. }
  85. private onBattle () {
  86. // 若上一关已完成则自动+1
  87. const lvl = this.sdm.getCurrentLevel();
  88. if (this.sdm.isLevelCompleted(lvl)) {
  89. const pd = this.sdm.getPlayerData();
  90. pd.currentLevel = lvl + 1;
  91. this.sdm.savePlayerData();
  92. }
  93. this.refreshLevelNumber();
  94. // 切场景 UI
  95. const mainUI = find('Canvas/MainUI');
  96. const gameUI = find('Canvas/GameLevelUI');
  97. if (mainUI) mainUI.active = false;
  98. if (gameUI) gameUI.active = true;
  99. const gmNode = find('Canvas/GameLevelUI/GameManager');
  100. const gm = gmNode?.getComponent(GameManager);
  101. gm?.restartGame();
  102. gm?.loadCurrentLevelConfig();
  103. // 显示 TopArea(拖拽引用),避免使用 find()
  104. if (this.topArea) this.topArea.active = true;
  105. // Camera move down instantly for battle prep
  106. // 兼容 "Camera" 或 "Main Camera" 等命名
  107. const camNode = find('Main Camera') || find('Camera') || find('Canvas/Camera');
  108. const gsm = camNode?.getComponent(GameStartMove);
  109. gsm?.moveDownInstant();
  110. }
  111. private onShop () {
  112. const mainUI = find('Canvas/MainUI');
  113. const shopUI = find('Canvas/ShopUI');
  114. if (mainUI) mainUI.active = false;
  115. if (shopUI) shopUI.active = true;
  116. }
  117. /* ================= 刷新 ================= */
  118. private refreshCurrency () {
  119. const mLbl = this.moneyLabel?.getComponent(Label) || this.moneyLabel as unknown as Label;
  120. if (mLbl) mLbl.string = this.format(this.sdm.getCoins());
  121. const dLbl = this.diamondLabel?.getComponent(Label) || this.diamondLabel as unknown as Label;
  122. if (dLbl) dLbl.string = this.format(this.sdm.getDiamonds());
  123. }
  124. private refreshLevelNumber(){
  125. if (this.levelNumberLabel) this.levelNumberLabel.string = `第 ${this.sdm.getCurrentLevel()} 关`;
  126. }
  127. private refreshAll(){
  128. this.refreshCurrency();
  129. this.refreshLevelNumber();
  130. this.refreshUpgradeInfo();
  131. }
  132. /** 刷新升级信息显示 */
  133. private refreshUpgradeInfo () {
  134. const gmNode = find('Canvas/GameLevelUI/GameManager');
  135. const gm = gmNode?.getComponent(GameManager);
  136. const hpLbl = this.upgradeHpLabel?.getComponent(Label);
  137. if (!gm || !hpLbl) return;
  138. const curHp = gm.getCurrentWallHealth?.() || 0;
  139. const nextHp = gm.getWallHealthByLevel?.(gm.getCurrentWallLevel?.() + 1) || curHp;
  140. hpLbl.string = `${curHp}>>${nextHp}`;
  141. }
  142. // 供外部(如 GameManager)调用的公共刷新接口
  143. public updateUI (): void {
  144. this.refreshAll();
  145. }
  146. /* =============== Util =============== */
  147. private format(n:number){ return n>=1000000? (n/1e6).toFixed(1)+'M' : n>=1000? (n/1e3).toFixed(1)+'K' : n.toString(); }
  148. }