NavBarController.ts 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import { _decorator, Color, Component, Node, Sprite, find } from 'cc';
  2. import EventBus, { GameEvents } from '../Core/EventBus';
  3. import { GameStartMove } from '../Animations/GameStartMove';
  4. const { ccclass, property } = _decorator;
  5. @ccclass('NavBarController')
  6. export class NavBarController extends Component {
  7. @property({ type: [Node] }) panels: Node[] = []; // 依次给 Main、Shop、Upgrade、Skill
  8. @property({ type: [Node] }) buttons: Node[] = []; // 依次给 Battle、Shop、Upgrade、Skill
  9. private normalColor = new Color(255, 255, 255, 255);
  10. private activeColor = new Color(255, 0, 0, 255); // 红色
  11. private lockedColor = new Color(128, 128, 128, 255); // 灰色(锁定状态)
  12. // 按钮锁定状态数组 - 对应 Battle、Shop、Upgrade、Skill 四个按钮
  13. private buttonLockStates: boolean[] = [false, true, false, false]; // 默认只锁定Shop按钮
  14. // GameStartMove组件引用,用于重置镜头位置
  15. private gameStartMoveComponent: GameStartMove = null;
  16. start () {
  17. // 默认打开 MainUI
  18. this.switchTo(0);
  19. // 初始化按钮状态,设置shop按钮为锁定状态
  20. this.updateButtonStates();
  21. // 设置事件监听
  22. this.setupEventListeners();
  23. }
  24. onDestroy() {
  25. // 移除事件监听
  26. this.removeEventListeners();
  27. }
  28. /**
  29. * 设置事件监听器
  30. */
  31. private setupEventListeners() {
  32. const eventBus = EventBus.getInstance();
  33. // 监听返回主菜单事件
  34. eventBus.on(GameEvents.RETURN_TO_MAIN_MENU, this.onReturnToMainMenu, this);
  35. }
  36. /**
  37. * 移除事件监听器
  38. */
  39. private removeEventListeners() {
  40. const eventBus = EventBus.getInstance();
  41. eventBus.off(GameEvents.RETURN_TO_MAIN_MENU, this.onReturnToMainMenu, this);
  42. }
  43. /**
  44. * 处理返回主菜单事件
  45. */
  46. private onReturnToMainMenu() {
  47. console.log('[NavBarController] 收到返回主菜单事件,切换到主界面');
  48. // 重置镜头位置到原始位置
  49. this.resetCameraPosition();
  50. // 切换到主界面(Battle按钮对应的Main面板,索引0)
  51. this.switchTo(0);
  52. }
  53. /**
  54. * 重置镜头位置到原始位置
  55. * 确保从游戏中返回主界面时镜头位置正常
  56. */
  57. private resetCameraPosition() {
  58. // 如果还没有获取GameStartMove组件,尝试获取
  59. if (!this.gameStartMoveComponent) {
  60. const cameraNode = find('Canvas/Main Camera');
  61. if (cameraNode) {
  62. this.gameStartMoveComponent = cameraNode.getComponent(GameStartMove);
  63. }
  64. }
  65. // 如果成功获取到组件,重置镜头位置
  66. if (this.gameStartMoveComponent) {
  67. console.log('[NavBarController] 重置镜头位置到原始位置');
  68. this.gameStartMoveComponent.resetCameraToOriginalPosition(0.3);
  69. } else {
  70. console.warn('[NavBarController] 未找到GameStartMove组件,无法重置镜头位置');
  71. }
  72. }
  73. onBattleClick () {
  74. // 检查Battle按钮是否被锁定(索引0)
  75. if (this.buttonLockStates[0]) {
  76. console.log('[NavBarController] Battle按钮被锁定,无法点击');
  77. // 发送Toast事件显示锁定提示
  78. EventBus.getInstance().emit(GameEvents.SHOW_TOAST, {
  79. message: '暂未解锁该功能!',
  80. duration: 2.0
  81. });
  82. return;
  83. }
  84. this.switchTo(0);
  85. }
  86. onUpgradeClick () {
  87. // 检查Upgrade按钮是否被锁定(索引2)
  88. if (this.buttonLockStates[2]) {
  89. console.log('[NavBarController] Upgrade按钮被锁定,无法点击');
  90. // 发送Toast事件显示锁定提示
  91. EventBus.getInstance().emit(GameEvents.SHOW_TOAST, {
  92. message: '暂未解锁该功能!',
  93. duration: 2.0
  94. });
  95. return;
  96. }
  97. this.switchTo(1);
  98. }
  99. onShopClick () {
  100. // 检查shop按钮是否被锁定(索引1)
  101. if (this.buttonLockStates[1]) {
  102. console.log('[NavBarController] Shop按钮被锁定,无法点击');
  103. // 发送Toast事件显示锁定提示
  104. EventBus.getInstance().emit(GameEvents.SHOW_TOAST, {
  105. message: '暂未解锁该功能!',
  106. duration: 2.0
  107. });
  108. return;
  109. }
  110. this.switchTo(2);
  111. }
  112. onSkillClick () {
  113. // 检查Skill按钮是否被锁定(索引3)
  114. if (this.buttonLockStates[3]) {
  115. console.log('[NavBarController] Skill按钮被锁定,无法点击');
  116. // 发送Toast事件显示锁定提示
  117. EventBus.getInstance().emit(GameEvents.SHOW_TOAST, {
  118. message: '暂未解锁该功能!',
  119. duration: 2.0
  120. });
  121. return;
  122. }
  123. this.switchTo(3);
  124. // 注意:滚动功能现在由SkillNodeGenerator组件通过装饰器直接处理
  125. }
  126. private switchTo (index: number) {
  127. // 显示对应面板
  128. this.panels.forEach((p, i) => p.active = i === index);
  129. // 按钮索引到面板索引的映射:根据实际的点击事件调用
  130. // 按钮索引: [0:Battle, 1:Shop, 2:Upgrade, 3:Skill]
  131. // 面板索引: [0:Main, 1:Shop, 2:Upgrade, 3:Skill]
  132. // 实际映射: Battle->Main(0), Shop->Upgrade(2), Upgrade->Shop(1), Skill->Skill(3)
  133. const buttonToPanelMap = [0, 2, 1, 3]; // Battle->Main(0), Shop->Upgrade(2), Upgrade->Shop(1), Skill->Skill(3)
  134. // 设置按钮颜色,考虑锁定状态
  135. this.buttons.forEach((btn, buttonIndex) => {
  136. const sp = btn.getComponent(Sprite);
  137. if (sp) {
  138. // 检查按钮是否被锁定
  139. if (this.buttonLockStates[buttonIndex]) {
  140. sp.color = this.lockedColor; // 锁定状态显示灰色
  141. } else {
  142. // 检查当前按钮对应的面板是否是激活的面板
  143. const panelIndex = buttonToPanelMap[buttonIndex];
  144. sp.color = (panelIndex === index) ? this.activeColor : this.normalColor;
  145. }
  146. }
  147. });
  148. }
  149. /**
  150. * 更新按钮状态,主要用于设置锁定按钮的视觉效果
  151. */
  152. private updateButtonStates() {
  153. // 按钮索引到面板索引的映射:根据实际的点击事件调用
  154. const buttonToPanelMap = [0, 2, 1, 3]; // Battle->Main(0), Shop->Upgrade(2), Upgrade->Shop(1), Skill->Skill(3)
  155. this.buttons.forEach((btn, buttonIndex) => {
  156. const sp = btn.getComponent(Sprite);
  157. if (sp) {
  158. if (this.buttonLockStates[buttonIndex]) {
  159. sp.color = this.lockedColor; // 设置锁定按钮为锁定颜色
  160. } else {
  161. // 对于未锁定的按钮,设置为正常颜色(除非它是当前激活的)
  162. // 这里我们需要知道当前激活的面板,但为了简化,先设置为正常颜色
  163. // 实际的激活状态会在switchTo中正确设置
  164. sp.color = this.normalColor;
  165. }
  166. }
  167. });
  168. }
  169. /**
  170. * 解锁指定按钮
  171. * @param buttonIndex 按钮索引 (0:Battle, 1:Shop, 2:Upgrade, 3:Skill)
  172. */
  173. public unlockButton(buttonIndex: number) {
  174. if (buttonIndex >= 0 && buttonIndex < this.buttonLockStates.length) {
  175. this.buttonLockStates[buttonIndex] = false;
  176. this.updateButtonStates();
  177. const buttonNames = ['Battle', 'Shop', 'Upgrade', 'Skill'];
  178. console.log(`[NavBarController] ${buttonNames[buttonIndex]}按钮已解锁`);
  179. }
  180. }
  181. /**
  182. * 锁定指定按钮
  183. * @param buttonIndex 按钮索引 (0:Battle, 1:Shop, 2:Upgrade, 3:Skill)
  184. */
  185. public lockButton(buttonIndex: number) {
  186. if (buttonIndex >= 0 && buttonIndex < this.buttonLockStates.length) {
  187. this.buttonLockStates[buttonIndex] = true;
  188. this.updateButtonStates();
  189. const buttonNames = ['Battle', 'Shop', 'Upgrade', 'Skill'];
  190. console.log(`[NavBarController] ${buttonNames[buttonIndex]}按钮已锁定`);
  191. }
  192. }
  193. /**
  194. * 检查指定按钮是否被锁定
  195. * @param buttonIndex 按钮索引 (0:Battle, 1:Shop, 2:Upgrade, 3:Skill)
  196. */
  197. public isButtonLocked(buttonIndex: number): boolean {
  198. if (buttonIndex >= 0 && buttonIndex < this.buttonLockStates.length) {
  199. return this.buttonLockStates[buttonIndex];
  200. }
  201. return false;
  202. }
  203. /**
  204. * 批量设置按钮锁定状态
  205. * @param lockStates 锁定状态数组 [Battle, Shop, Upgrade, Skill]
  206. */
  207. public setButtonLockStates(lockStates: boolean[]) {
  208. if (lockStates.length === 4) {
  209. this.buttonLockStates = [...lockStates];
  210. this.updateButtonStates();
  211. console.log('[NavBarController] 按钮锁定状态已更新:', lockStates);
  212. }
  213. }
  214. /**
  215. * 获取当前所有按钮的锁定状态
  216. */
  217. public getButtonLockStates(): boolean[] {
  218. return [...this.buttonLockStates];
  219. }
  220. }