TopBarController.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // TopBarController.ts
  2. import { _decorator, Component, Node, Button, Label, find } from 'cc';
  3. import { SaveDataManager } from '../LevelSystem/SaveDataManager';
  4. import EventBus, { GameEvents } from '../Core/EventBus';
  5. import { Audio } from '../AudioManager/AudioManager';
  6. import { AdManager } from '../Ads/AdManager';
  7. import { NavBarController } from './NavBarController';
  8. const { ccclass, property } = _decorator;
  9. @ccclass('TopBarController')
  10. export class TopBarController extends Component {
  11. /* 顶部资源 & 关卡 */
  12. @property(Node) moneyAddBtn: Node = null; // 绿色 +
  13. @property(Node) diamondAddBtn: Node = null; // 紫色 +
  14. @property(Node) moneyLabel: Node = null; // 钞票数字
  15. @property(Node) diamondLabel: Node = null; // 钻石数字
  16. private sdm: SaveDataManager = null;
  17. onLoad() {
  18. this.sdm = SaveDataManager.getInstance();
  19. this.bindButtons();
  20. this.refreshAll();
  21. // 监听货币变化事件
  22. this.setupEventListeners();
  23. }
  24. onDestroy() {
  25. // 移除事件监听
  26. this.removeEventListeners();
  27. }
  28. /* 设置事件监听 */
  29. private setupEventListeners() {
  30. const eventBus = EventBus.getInstance();
  31. // 监听游戏开始事件,初始显示货币
  32. eventBus.on(GameEvents.GAME_START, this.refreshCurrency, this);
  33. // 监听货币变化事件
  34. eventBus.on(GameEvents.CURRENCY_CHANGED, this.refreshCurrency, this);
  35. // 监听UI重置事件
  36. eventBus.on(GameEvents.RESET_UI_STATES, this.refreshAll, this);
  37. }
  38. /* 移除事件监听 */
  39. private removeEventListeners() {
  40. const eventBus = EventBus.getInstance();
  41. eventBus.off(GameEvents.GAME_START, this.refreshCurrency, this);
  42. eventBus.off(GameEvents.CURRENCY_CHANGED, this.refreshCurrency, this);
  43. eventBus.off(GameEvents.RESET_UI_STATES, this.refreshAll, this);
  44. }
  45. /* 绑定按钮事件 */
  46. //看广告才能获取的货币
  47. private bindButtons() {
  48. // 顶部加号:直接跳转到商店界面;如果已在商店界面则不做任何反馈
  49. this.moneyAddBtn?.on(Button.EventType.CLICK, this.onPlusClick, this);
  50. this.diamondAddBtn?.on(Button.EventType.CLICK, this.onPlusClick, this);
  51. }
  52. private onPlusClick() {
  53. this.openShopIfNotAlready();
  54. }
  55. private openShopIfNotAlready() {
  56. const navBarNode = find('Canvas/NavBar');
  57. if (!navBarNode) {
  58. console.warn('[TopBarController] 未找到 Canvas/NavBar 节点,无法打开商店');
  59. return;
  60. }
  61. const navBar = navBarNode.getComponent(NavBarController);
  62. if (!navBar) {
  63. console.warn('[TopBarController] NavBarController 未挂载,无法打开商店');
  64. return;
  65. }
  66. // 如果已经是商店面板,什么都不做
  67. if (navBar.isShopPanelActive()) {
  68. return;
  69. }
  70. // 直接打开商店面板(忽略按钮锁定状态)
  71. navBar.openShopPanel();
  72. }
  73. /* ================= 业务逻辑 ================= */
  74. private addMoney(v: number) {
  75. // 播放UI点击音效
  76. Audio.playUISound('data/弹球音效/ui play');
  77. // 显示激励视频广告
  78. AdManager.getInstance().showRewardedVideoAd(
  79. () => {
  80. // 广告观看完成,给予奖励
  81. this.sdm.addMoney(v, 'ad');
  82. // 触发货币变化事件
  83. EventBus.getInstance().emit(GameEvents.CURRENCY_CHANGED);
  84. },
  85. (error) => {
  86. console.error('[TopBarController] 广告显示失败:', error);
  87. // 可以选择不给予奖励或给予部分奖励
  88. }
  89. );
  90. }
  91. private addDiamonds(v: number) {
  92. // 播放UI点击音效
  93. Audio.playUISound('data/弹球音效/ui play');
  94. // 显示激励视频广告
  95. AdManager.getInstance().showRewardedVideoAd(
  96. () => {
  97. // 广告观看完成,给予奖励
  98. this.sdm.addDiamonds(v, 'ad');
  99. // 触发货币变化事件
  100. EventBus.getInstance().emit(GameEvents.CURRENCY_CHANGED);
  101. },
  102. (error) => {
  103. console.error('[TopBarController] 广告显示失败:', error);
  104. // 可以选择不给予奖励或给予部分奖励
  105. }
  106. );
  107. }
  108. /* ================= 刷新 ================= */
  109. private refreshCurrency() {
  110. // 确保SaveDataManager已初始化
  111. if (!this.sdm) {
  112. console.warn('[TopBarController] SaveDataManager未初始化,跳过货币刷新');
  113. return;
  114. }
  115. // 如果SaveDataManager还没有调用initialize(),先初始化
  116. this.sdm.initialize();
  117. const currentCoins = this.sdm.getMoney();
  118. const currentDiamonds = this.sdm.getDiamonds();
  119. console.log(`[TopBarController] 刷新货币显示 - 钞票: ${currentCoins}, 钻石: ${currentDiamonds}`);
  120. const mLbl = this.moneyLabel?.getComponent(Label) || this.moneyLabel as unknown as Label;
  121. if (mLbl) {
  122. const formattedCoins = this.format(currentCoins);
  123. mLbl.string = formattedCoins;
  124. console.log(`[TopBarController] 钞票显示更新为: ${formattedCoins}`);
  125. }
  126. const dLbl = this.diamondLabel?.getComponent(Label) || this.diamondLabel as unknown as Label;
  127. if (dLbl) {
  128. const formattedDiamonds = this.format(currentDiamonds);
  129. dLbl.string = formattedDiamonds;
  130. console.log(`[TopBarController] 钻石显示更新为: ${formattedDiamonds}`);
  131. }
  132. }
  133. private refreshAll() {
  134. this.refreshCurrency();
  135. }
  136. // 供外部调用的公共刷新接口(保留以防其他地方需要手动刷新)
  137. public updateUI(): void {
  138. this.refreshAll();
  139. }
  140. /* =============== Util =============== */
  141. private format(n: number) {
  142. return n >= 1000000 ? (n / 1e6).toFixed(1) + 'M' : n >= 1000 ? (n / 1e3).toFixed(1) + 'K' : n.toString();
  143. }
  144. }