MainUIControlller.ts 6.5 KB

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