UpgradeAni.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { _decorator, Component, Node, Tween, tween, Vec3, Material, Sprite, resources } from 'cc';
  2. import { Audio } from '../../AudioManager/AudioManager';
  3. const { ccclass, property } = _decorator;
  4. /**
  5. * 植物升级动画控制器
  6. * 负责管理植物升级相关的动画效果
  7. */
  8. @ccclass('UpgradeAni')
  9. export class UpgradeAni extends Component {
  10. @property(Node)
  11. weaponSpriteNode: Node = null;
  12. /**
  13. * 植物升级成功动画
  14. * 播放植物图标的放大缩小动画,并在升级期间应用扫描效果材质,同时播放升级音效
  15. * @param weaponIconNode 植物图标节点
  16. */
  17. public playWeaponUpgradeAnimation(weaponIconNode: Node): Promise<void> {
  18. return new Promise((resolve) => {
  19. if (!weaponIconNode) {
  20. resolve();
  21. return;
  22. }
  23. // 停止之前的动画,防止快速点击时动画冲突
  24. Tween.stopAllByTarget(weaponIconNode);
  25. // 重置到原始缩放状态,确保动画从正确的状态开始
  26. weaponIconNode.setScale(Vec3.ONE);
  27. // 保存原始缩放值
  28. const originalScale = Vec3.ONE.clone();
  29. let weaponSprite: Sprite = null;
  30. let originalMaterial: Material = null;
  31. console.log('[UpgradeAni] 开始武器升级动画,weaponSpriteNode:', this.weaponSpriteNode);
  32. // 播放植物升级音效
  33. Audio.playUISound('data/弹球音效/equipment level up finish');
  34. // 使用装饰器引用的WeaponSprite节点,获取其Sprite组件并保存原始材质
  35. if (this.weaponSpriteNode) {
  36. console.log('[UpgradeAni] 找到weaponSpriteNode,开始获取Sprite组件');
  37. weaponSprite = this.weaponSpriteNode.getComponent(Sprite);
  38. if (weaponSprite) {
  39. console.log('[UpgradeAni] 找到Sprite组件,开始加载材质');
  40. // 保存原始材质,优先保存customMaterial,如果没有则保存当前material
  41. originalMaterial = weaponSprite.customMaterial || weaponSprite.material;
  42. console.log('[UpgradeAni] 原始材质:', originalMaterial);
  43. // 加载并应用扫描效果材质
  44. resources.load('shaders/scan-effect', Material, (err, scanMaterial) => {
  45. console.log('[UpgradeAni] 材质加载回调,err:', err, 'scanMaterial:', scanMaterial);
  46. if (!err && scanMaterial && weaponSprite) {
  47. weaponSprite.material = scanMaterial;
  48. console.log('[UpgradeAni] 应用扫描效果材质成功');
  49. } else {
  50. console.warn('[UpgradeAni] 加载扫描效果材质失败:', err);
  51. }
  52. });
  53. } else {
  54. console.warn('[UpgradeAni] weaponSpriteNode上没有找到Sprite组件');
  55. }
  56. } else {
  57. console.warn('[UpgradeAni] weaponSpriteNode为null,请在编辑器中设置');
  58. }
  59. // 创建缩放动画:放大到1.5倍再立即缩小回原始大小
  60. const scaleAnimation = tween(weaponIconNode)
  61. .to(0.25, { scale: new Vec3(originalScale.x * 1.5, originalScale.y * 1.5, originalScale.z) }, {
  62. easing: 'sineOut'
  63. })
  64. .to(0.25, { scale: originalScale }, {
  65. easing: 'sineIn'
  66. })
  67. .call(() => {
  68. // 动画结束后恢复原始材质
  69. if (weaponSprite && originalMaterial) {
  70. // 如果原始材质是customMaterial,则恢复customMaterial
  71. if (weaponSprite.customMaterial === originalMaterial) {
  72. weaponSprite.material = weaponSprite.customMaterial;
  73. } else {
  74. weaponSprite.material = originalMaterial;
  75. }
  76. console.log('[UpgradeAni] 恢复原始材质成功');
  77. } else if (weaponSprite) {
  78. // 如果没有保存的原始材质,尝试恢复到customMaterial
  79. if (weaponSprite.customMaterial) {
  80. weaponSprite.material = weaponSprite.customMaterial;
  81. console.log('[UpgradeAni] 恢复到customMaterial');
  82. } else {
  83. weaponSprite.material = null;
  84. console.log('[UpgradeAni] 恢复到默认材质');
  85. }
  86. }
  87. resolve();
  88. });
  89. // 播放缩放动画
  90. scaleAnimation.start();
  91. });
  92. }
  93. }