SkillButtonAnimator.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { _decorator, Component, Node, Vec3, tween, find, Sprite, Color } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. /**
  4. * SkillButtonAnimator
  5. * 负责技能按钮的缩放 / 移动动画和星星闪烁效果。
  6. * 提供 playShrink 接口供外部调用。
  7. */
  8. @ccclass('SkillButtonAnimator')
  9. export class SkillButtonAnimator extends Component {
  10. private _origScale: Vec3 = new Vec3();
  11. private _origPos: Vec3 = new Vec3();
  12. private _starNodes: Node[] = [];
  13. private _blinkTween: any = null;
  14. // 星星颜色配置
  15. private readonly STAR_ACTIVE_COLOR = new Color(255, 255, 255, 255); // 亮起的星星
  16. private readonly STAR_INACTIVE_COLOR = new Color(58, 37, 37, 255); // 未亮起的星星 (3A2525)
  17. onLoad() {
  18. // 记录初始位置、缩放,用于恢复
  19. this._origScale.set(this.node.scale);
  20. this._origPos.set(this.node.position);
  21. // 查找星星节点
  22. this.findStarNodes();
  23. }
  24. /**
  25. * 查找星星节点
  26. */
  27. private findStarNodes() {
  28. const starContainer = this.node.getChildByName('Star');
  29. if (starContainer) {
  30. // 查找所有星星节点 (xx-1, xx-2, xx-3, xx-4, xx-5)
  31. for (let i = 1; i <= 5; i++) {
  32. const starNode = starContainer.getChildByName(`xx-${i}`);
  33. if (starNode) {
  34. this._starNodes.push(starNode);
  35. }
  36. }
  37. }
  38. }
  39. /**
  40. * 设置技能等级并更新星星显示
  41. * @param currentLevel 当前等级 (0-5)
  42. */
  43. public setSkillLevel(currentLevel: number) {
  44. // 停止之前的闪烁动画
  45. this.stopBlinkAnimation();
  46. // 更新星星显示
  47. this._starNodes.forEach((starNode, index) => {
  48. const sprite = starNode.getComponent(Sprite);
  49. if (sprite) {
  50. if (index < currentLevel) {
  51. // 已亮起的星星
  52. sprite.color = this.STAR_ACTIVE_COLOR;
  53. } else {
  54. // 未亮起的星星
  55. sprite.color = this.STAR_INACTIVE_COLOR;
  56. }
  57. }
  58. });
  59. // 如果当前等级小于最大等级,开始闪烁下一颗星星
  60. if (currentLevel < 5) {
  61. this.startBlinkAnimation(currentLevel);
  62. }
  63. }
  64. /**
  65. * 开始星星闪烁动画
  66. * @param nextStarIndex 下一颗要闪烁的星星索引 (0-4)
  67. */
  68. private startBlinkAnimation(nextStarIndex: number) {
  69. if (nextStarIndex >= this._starNodes.length) return;
  70. const nextStar = this._starNodes[nextStarIndex];
  71. const sprite = nextStar.getComponent(Sprite);
  72. if (!sprite) return;
  73. // 创建闪烁动画:在亮起和未亮起之间切换
  74. this._blinkTween = tween(sprite)
  75. .to(0.5, { color: this.STAR_ACTIVE_COLOR })
  76. .to(0.5, { color: this.STAR_INACTIVE_COLOR })
  77. .union()
  78. .repeatForever()
  79. .start();
  80. }
  81. /**
  82. * 停止星星闪烁动画
  83. */
  84. private stopBlinkAnimation() {
  85. if (this._blinkTween) {
  86. this._blinkTween.stop();
  87. this._blinkTween = null;
  88. }
  89. }
  90. /**
  91. * 播放缩小并(可选)移动到指定目标位置的动画。
  92. * @param duration 动画时长(秒)
  93. * @param targetPos 目标位置(节点本地坐标系),不传则保持原位置
  94. * @param onComplete 完成回调
  95. */
  96. public playShrink(duration: number = 0.3, targetPos?: Vec3, onComplete?: () => void) {
  97. // 停止闪烁动画
  98. this.stopBlinkAnimation();
  99. // 若目标位置存在,则先 tween 到该位置;否则只缩放
  100. const props: any = { scale: new Vec3(0, 0, 0) };
  101. if (targetPos) {
  102. props.position = targetPos;
  103. }
  104. tween(this.node)
  105. .to(duration, props, { easing: 'quadIn' })
  106. .call(() => {
  107. // 动画结束后隐藏节点,但允许后续 resetState 恢复
  108. this.node.active = false;
  109. if (onComplete) onComplete();
  110. })
  111. .start();
  112. this.node.setPosition(this._origPos);
  113. }
  114. public resetState() {
  115. // 停止闪烁动画
  116. this.stopBlinkAnimation();
  117. // Reset scale, position, opacity, etc. as needed
  118. this.node.setScale(Vec3.ONE);
  119. this.node.active = true;
  120. this.node.setPosition(this._origPos);
  121. // 重置星星显示为0级状态
  122. this.setSkillLevel(0);
  123. }
  124. onDestroy() {
  125. // 清理闪烁动画
  126. this.stopBlinkAnimation();
  127. }
  128. }
  129. export default SkillButtonAnimator;