ButtonEffectsManager.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import { _decorator, Component, Node, Button, Vec3, Color, UIOpacity, Enum } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. /**
  4. * Button effect types
  5. */
  6. enum ButtonEffectType {
  7. MOVE_DOWN = 0,
  8. DARKEN = 1
  9. }
  10. @ccclass('ButtonEffectsManager')
  11. export class ButtonEffectsManager extends Component {
  12. @property({
  13. type: [Button],
  14. tooltip: 'The buttons to apply effects to'
  15. })
  16. buttons: Button[] = [];
  17. @property({
  18. type: Enum(ButtonEffectType),
  19. tooltip: 'Effect type: 0 for move down, 1 for darken'
  20. })
  21. effectType: ButtonEffectType = ButtonEffectType.MOVE_DOWN;
  22. @property({
  23. tooltip: 'How much to move the button down (in pixels)',
  24. visible: function(this: ButtonEffectsManager) {
  25. return this.effectType === ButtonEffectType.MOVE_DOWN;
  26. }
  27. })
  28. moveDistance: number = 5;
  29. @property({
  30. tooltip: 'How much to darken the button (0-1)',
  31. range: [0, 1, 0.05],
  32. slide: true,
  33. visible: function(this: ButtonEffectsManager) {
  34. return this.effectType === ButtonEffectType.DARKEN;
  35. }
  36. })
  37. darkenAmount: number = 0.2;
  38. private originalPositions: Map<string, Vec3> = new Map();
  39. private originalOpacities: Map<string, number> = new Map();
  40. start() {
  41. // Register all buttons
  42. this.registerButtons();
  43. }
  44. /**
  45. * Register all buttons in the buttons array
  46. */
  47. registerButtons() {
  48. this.buttons.forEach(button => {
  49. if (button) {
  50. this.registerButton(button);
  51. }
  52. });
  53. }
  54. /**
  55. * Register a single button with press effects
  56. * @param button The button to register
  57. */
  58. registerButton(button: Button) {
  59. const buttonNode = button.node;
  60. const buttonId = buttonNode.uuid;
  61. // Store original position for move effect
  62. if (this.effectType === ButtonEffectType.MOVE_DOWN) {
  63. const originalPos = buttonNode.position.clone();
  64. this.originalPositions.set(buttonId, originalPos);
  65. }
  66. // Store original opacity for darken effect
  67. else if (this.effectType === ButtonEffectType.DARKEN) {
  68. const uiOpacity = buttonNode.getComponent(UIOpacity);
  69. if (uiOpacity) {
  70. this.originalOpacities.set(buttonId, uiOpacity.opacity);
  71. } else {
  72. // Add UIOpacity if it doesn't exist
  73. const newUIOpacity = buttonNode.addComponent(UIOpacity);
  74. this.originalOpacities.set(buttonId, newUIOpacity.opacity);
  75. }
  76. }
  77. // Add button events
  78. button.node.on(Node.EventType.TOUCH_START, () => this.onButtonPressed(buttonId), this);
  79. button.node.on(Node.EventType.TOUCH_END, () => this.onButtonReleased(buttonId), this);
  80. button.node.on(Node.EventType.TOUCH_CANCEL, () => this.onButtonReleased(buttonId), this);
  81. }
  82. /**
  83. * Handle button press
  84. * @param buttonId The unique ID of the button
  85. */
  86. onButtonPressed(buttonId: string) {
  87. const button = this.getButtonById(buttonId);
  88. if (!button) return;
  89. if (this.effectType === ButtonEffectType.MOVE_DOWN) {
  90. const originalPos = this.originalPositions.get(buttonId);
  91. if (originalPos) {
  92. const newPos = originalPos.clone();
  93. newPos.y -= this.moveDistance;
  94. button.node.position = newPos;
  95. }
  96. } else if (this.effectType === ButtonEffectType.DARKEN) {
  97. const uiOpacity = button.node.getComponent(UIOpacity);
  98. if (uiOpacity) {
  99. const originalOpacity = this.originalOpacities.get(buttonId) || 255;
  100. uiOpacity.opacity = originalOpacity * (1 - this.darkenAmount);
  101. }
  102. }
  103. }
  104. /**
  105. * Handle button release
  106. * @param buttonId The unique ID of the button
  107. */
  108. onButtonReleased(buttonId: string) {
  109. const button = this.getButtonById(buttonId);
  110. if (!button) return;
  111. if (this.effectType === ButtonEffectType.MOVE_DOWN) {
  112. const originalPos = this.originalPositions.get(buttonId);
  113. if (originalPos) {
  114. button.node.position = originalPos.clone();
  115. }
  116. } else if (this.effectType === ButtonEffectType.DARKEN) {
  117. const uiOpacity = button.node.getComponent(UIOpacity);
  118. if (uiOpacity) {
  119. const originalOpacity = this.originalOpacities.get(buttonId) || 255;
  120. uiOpacity.opacity = originalOpacity;
  121. }
  122. }
  123. }
  124. /**
  125. * Find a button by its ID
  126. * @param buttonId The unique ID of the button
  127. * @returns The button component or null if not found
  128. */
  129. private getButtonById(buttonId: string): Button | null {
  130. for (const button of this.buttons) {
  131. if (button && button.node.uuid === buttonId) {
  132. return button;
  133. }
  134. }
  135. return null;
  136. }
  137. /**
  138. * Manually add a button to the manager
  139. * @param button The button to add
  140. */
  141. public addButton(button: Button) {
  142. if (!this.buttons.some(btn => btn === button)) {
  143. this.buttons.push(button);
  144. this.registerButton(button);
  145. }
  146. }
  147. /**
  148. * Remove a button from the manager
  149. * @param button The button to remove
  150. */
  151. public removeButton(button: Button) {
  152. const index = this.buttons.indexOf(button);
  153. if (index !== -1) {
  154. const buttonId = button.node.uuid;
  155. // Remove event listeners
  156. button.node.off(Node.EventType.TOUCH_START, () => this.onButtonPressed(buttonId), this);
  157. button.node.off(Node.EventType.TOUCH_END, () => this.onButtonReleased(buttonId), this);
  158. button.node.off(Node.EventType.TOUCH_CANCEL, () => this.onButtonReleased(buttonId), this);
  159. // Remove button from array
  160. this.buttons.splice(index, 1);
  161. // Clean up stored data
  162. this.originalPositions.delete(buttonId);
  163. this.originalOpacities.delete(buttonId);
  164. }
  165. }
  166. }