ButtonManager.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { _decorator, Component, Node, Button, Tween, tween, Vec3 } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. @ccclass('ButtonManager')
  4. export class ButtonManager extends Component {
  5. private static _instance: ButtonManager = null;
  6. @property({ type: [Button], displayName: "按钮数组" })
  7. public buttons: Button[] = [];
  8. // 动画参数
  9. private readonly SCALE_REDUCTION = 0.15; // 缩放减少量
  10. private readonly ANIMATION_DURATION = 0.1; // 动画持续时间
  11. public static get instance(): ButtonManager {
  12. return ButtonManager._instance;
  13. }
  14. onLoad() {
  15. // 设置单例
  16. if (ButtonManager._instance === null) {
  17. ButtonManager._instance = this;
  18. } else {
  19. this.destroy();
  20. return;
  21. }
  22. // 初始化按钮事件
  23. this.initButtonEvents();
  24. }
  25. onDestroy() {
  26. if (ButtonManager._instance === this) {
  27. ButtonManager._instance = null;
  28. }
  29. }
  30. private initButtonEvents() {
  31. this.buttons.forEach((button, index) => {
  32. if (button && button.node) {
  33. // 添加点击事件监听
  34. button.node.on(Button.EventType.CLICK, () => {
  35. this.playClickAnimation(button.node);
  36. }, this);
  37. // 不强制设置初始缩放,保持按钮原有缩放
  38. }
  39. });
  40. }
  41. /**
  42. * 播放按钮点击动画
  43. * @param buttonNode 按钮节点
  44. */
  45. private playClickAnimation(buttonNode: Node) {
  46. if (!buttonNode) return;
  47. // 停止之前的动画
  48. Tween.stopAllByTarget(buttonNode);
  49. // 获取当前缩放值
  50. const currentScale = buttonNode.scale;
  51. const originalScale = currentScale.clone();
  52. // 计算目标缩放值(当前缩放减去0.15)
  53. const targetScale = new Vec3(
  54. Math.max(0.1, currentScale.x - this.SCALE_REDUCTION), // 最小缩放限制为0.1
  55. Math.max(0.1, currentScale.y - this.SCALE_REDUCTION),
  56. currentScale.z
  57. );
  58. // 创建缩放动画:先缩小,然后回到原来大小
  59. tween(buttonNode)
  60. .to(this.ANIMATION_DURATION, { scale: targetScale })
  61. .to(this.ANIMATION_DURATION, { scale: originalScale })
  62. .start();
  63. }
  64. /**
  65. * 手动添加按钮到管理器
  66. * @param button 要添加的按钮
  67. */
  68. public addButton(button: Button) {
  69. if (button && this.buttons.indexOf(button) === -1) {
  70. this.buttons.push(button);
  71. // 为新添加的按钮设置事件
  72. if (button.node) {
  73. button.node.on(Button.EventType.CLICK, () => {
  74. this.playClickAnimation(button.node);
  75. }, this);
  76. // 不强制设置缩放,保持按钮原有缩放
  77. }
  78. }
  79. }
  80. /**
  81. * 从管理器中移除按钮
  82. * @param button 要移除的按钮
  83. */
  84. public removeButton(button: Button) {
  85. const index = this.buttons.indexOf(button);
  86. if (index !== -1) {
  87. // 移除事件监听
  88. if (button.node) {
  89. button.node.off(Button.EventType.CLICK, this.playClickAnimation, this);
  90. }
  91. this.buttons.splice(index, 1);
  92. }
  93. }
  94. /**
  95. * 清空所有按钮
  96. */
  97. public clearAllButtons() {
  98. this.buttons.forEach(button => {
  99. if (button && button.node) {
  100. button.node.off(Button.EventType.CLICK, this.playClickAnimation, this);
  101. }
  102. });
  103. this.buttons = [];
  104. }
  105. }