UpgradeAni.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import { _decorator, Component, Node, Tween, tween,Vec3 } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. /**
  4. * 升级面板动画控制器
  5. * 负责管理升级面板的显示和隐藏动画
  6. */
  7. @ccclass('UpgradeAni')
  8. export class UpgradeAni extends Component {
  9. /**
  10. * 显示面板动画
  11. * 面板从小到大的缩放动画,从屏幕中央弹出
  12. */
  13. public showPanel(): Promise<void> {
  14. return new Promise((resolve) => {
  15. // 设置初始状态:缩小到0,位置居中
  16. this.node.setScale(Vec3.ZERO);
  17. this.node.setPosition(0, 0, 0); // 确保面板在屏幕正中间
  18. this.node.active = true;
  19. // 缩放动画:从0放大到1
  20. tween(this.node)
  21. .to(0.3, { scale: new Vec3(1, 1, 1) }, {
  22. easing: 'backOut' // 使用回弹缓动效果
  23. })
  24. .call(() => {
  25. resolve();
  26. })
  27. .start();
  28. });
  29. }
  30. /**
  31. * 隐藏面板动画
  32. * 面板从大到小的缩放动画
  33. */
  34. public hidePanel(): Promise<void> {
  35. return new Promise((resolve) => {
  36. // 缩放动画:从1缩小到0
  37. tween(this.node)
  38. .to(0.2, { scale: Vec3.ZERO }, {
  39. easing: 'backIn' // 使用回弹缓动效果
  40. })
  41. .call(() => {
  42. this.node.active = false;
  43. resolve();
  44. })
  45. .start();
  46. });
  47. }
  48. /**
  49. * 立即隐藏面板(无动画)
  50. */
  51. public hidePanelImmediate(): void {
  52. this.node.setScale(Vec3.ZERO);
  53. this.node.active = false;
  54. }
  55. /**
  56. * 立即显示面板(无动画)
  57. */
  58. public showPanelImmediate(): void {
  59. this.node.setScale(Vec3.ONE);
  60. this.node.setPosition(0, 0, 0); // 确保面板在屏幕正中间
  61. this.node.active = true;
  62. }
  63. /**
  64. * 武器升级成功动画
  65. * 播放武器图标的放大缩小动画
  66. * @param weaponIconNode 武器图标节点
  67. */
  68. public playWeaponUpgradeAnimation(weaponIconNode: Node): Promise<void> {
  69. return new Promise((resolve) => {
  70. if (!weaponIconNode) {
  71. resolve();
  72. return;
  73. }
  74. // 停止之前的动画,防止快速点击时动画冲突
  75. Tween.stopAllByTarget(weaponIconNode);
  76. // 重置到原始缩放状态,确保动画从正确的状态开始
  77. weaponIconNode.setScale(Vec3.ONE);
  78. // 保存原始缩放值
  79. const originalScale = Vec3.ONE.clone();
  80. // 创建缩放动画:放大到1.5倍再立即缩小回原始大小
  81. const scaleAnimation = tween(weaponIconNode)
  82. .to(0.25, { scale: new Vec3(originalScale.x * 1.5, originalScale.y * 1.5, originalScale.z) }, {
  83. easing: 'sineOut'
  84. })
  85. .to(0.25, { scale: originalScale }, {
  86. easing: 'sineIn'
  87. });
  88. // 只播放缩放动画
  89. scaleAnimation.call(() => resolve()).start();
  90. });
  91. }
  92. /**
  93. * UP图标提示动画
  94. * 播放缩小到0.7倍再放大到原来大小的重复动画,直到条件不满足为止
  95. * @param upIconNode UP图标节点
  96. * @param checkCondition 检查条件的回调函数,返回false时停止动画
  97. */
  98. public playUpIconAnimation(upIconNode: Node, checkCondition?: () => boolean): void {
  99. if (!upIconNode) return;
  100. // 停止之前的动画
  101. Tween.stopAllByTarget(upIconNode);
  102. // 保存原始缩放值
  103. const originalScale = upIconNode.scale.clone();
  104. // 如果没有提供检查条件,使用默认的无限重复动画
  105. if (!checkCondition) {
  106. const scaleAnimation = tween(upIconNode)
  107. .to(0.5, { scale: new Vec3(originalScale.x * 0.7, originalScale.y * 0.7, originalScale.z) }, {
  108. easing: 'sineInOut'
  109. })
  110. .to(0.5, { scale: originalScale }, {
  111. easing: 'sineInOut'
  112. })
  113. .repeatForever(); // 无限重复
  114. scaleAnimation.start();
  115. return;
  116. }
  117. // 带条件检查的动画循环
  118. const playAnimationCycle = () => {
  119. // 在每次动画循环开始前检查条件
  120. if (!checkCondition()) {
  121. // 条件不满足,停止动画并恢复原始缩放
  122. this.stopUpIconAnimation(upIconNode);
  123. return;
  124. }
  125. // 创建一次完整的缩放动画循环
  126. const scaleAnimation = tween(upIconNode)
  127. .to(0.5, { scale: new Vec3(originalScale.x * 0.7, originalScale.y * 0.7, originalScale.z) }, {
  128. easing: 'sineInOut'
  129. })
  130. .to(0.5, { scale: originalScale }, {
  131. easing: 'sineInOut'
  132. })
  133. .call(() => {
  134. // 一次循环完成后,递归调用下一次循环
  135. playAnimationCycle();
  136. });
  137. scaleAnimation.start();
  138. };
  139. // 开始第一次动画循环
  140. playAnimationCycle();
  141. }
  142. /**
  143. * 停止UP图标动画
  144. * @param upIconNode UP图标节点
  145. */
  146. public stopUpIconAnimation(upIconNode: Node): void {
  147. if (!upIconNode) return;
  148. // 停止所有动画
  149. Tween.stopAllByTarget(upIconNode);
  150. // 恢复原始缩放
  151. upIconNode.setScale(Vec3.ONE);
  152. }
  153. }