SkillSelectionController.ts 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { _decorator, Component, Node, Button, Vec3, find } from 'cc';
  2. import SkillButtonAnimator from './SkillButtonAnimator';
  3. import { GameManager } from '../../LevelSystem/GameManager';
  4. const { ccclass, property } = _decorator;
  5. /**
  6. * SkillSelectionController
  7. * 放在 Canvas/SelectSkillUI 节点上。
  8. * 负责监听技能按钮点击,并按顺序播放缩小动画,最后关闭整个 SelectSkillUI。
  9. */
  10. @ccclass('SkillSelectionController')
  11. export class SkillSelectionController extends Component {
  12. @property({ type: [Node], tooltip: '技能按钮节点列表,留空则自动从 SkillsContainer 获取' })
  13. public skillButtons: Node[] = [];
  14. @property({ tooltip: '缩小动画时长(秒)' })
  15. public shrinkDuration: number = 0.25;
  16. private _clicked = false;
  17. start() {
  18. // 自动收集按钮
  19. if (this.skillButtons.length === 0) {
  20. const container = this.node.getChildByName('SkillsContainer');
  21. if (container) {
  22. this.skillButtons = container.children;
  23. }
  24. }
  25. // 绑定点击事件
  26. this.skillButtons.forEach(btn => {
  27. const buttonComp = btn.getComponent(Button);
  28. if (buttonComp) {
  29. buttonComp.node.on(Button.EventType.CLICK, () => this.onSkillSelected(btn));
  30. } else {
  31. // 兜底:直接监听触摸
  32. btn.on(Node.EventType.TOUCH_END, () => this.onSkillSelected(btn));
  33. }
  34. });
  35. }
  36. /**
  37. * 玩家选择某技能按钮
  38. */
  39. private onSkillSelected(selectedBtn: Node) {
  40. if (this._clicked) return; // 只允许一次
  41. this._clicked = true;
  42. // 禁用所有按钮交互
  43. this.skillButtons.forEach(btn => {
  44. const b = btn.getComponent(Button);
  45. if (b) b.interactable = false;
  46. });
  47. const otherBtns = this.skillButtons.filter(btn => btn !== selectedBtn);
  48. let finishedOthers = 0;
  49. // 所有其他按钮完成动画后,再收缩选中按钮
  50. const onOtherFinished = () => {
  51. finishedOthers++;
  52. if (finishedOthers >= otherBtns.length) {
  53. // 收缩选中按钮
  54. const selAnim = selectedBtn.getComponent(SkillButtonAnimator);
  55. selAnim?.playShrink(this.shrinkDuration, undefined, () => {
  56. // 关闭整个 UI
  57. this.node.active = false;
  58. // 恢复游戏并重置能量
  59. const gm = this.getGameManager();
  60. if (gm) {
  61. gm.resetEnergy();
  62. gm.resumeGame();
  63. }
  64. });
  65. }
  66. };
  67. // 播放其他按钮动画
  68. const targetPos = selectedBtn.position.clone();
  69. otherBtns.forEach(btn => {
  70. const anim = btn.getComponent(SkillButtonAnimator);
  71. anim?.playShrink(this.shrinkDuration, targetPos, onOtherFinished);
  72. });
  73. }
  74. private _gameManager: GameManager = null;
  75. private getGameManager(): GameManager {
  76. if (this._gameManager && this._gameManager.isValid) return this._gameManager;
  77. const gmNode = find('GameManager');
  78. if (gmNode) {
  79. this._gameManager = gmNode.getComponent(GameManager);
  80. }
  81. return this._gameManager;
  82. }
  83. }
  84. export default SkillSelectionController;