UpgradeAni.ts 4.7 KB

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