import { _decorator, Component, Node, Tween, tween, Vec3, Material, Sprite, resources } from 'cc'; import { Audio } from '../../AudioManager/AudioManager'; const { ccclass, property } = _decorator; /** * 植物升级动画控制器 * 负责管理植物升级相关的动画效果 */ @ccclass('UpgradeAni') export class UpgradeAni extends Component { @property(Node) weaponSpriteNode: Node = null; /** * 植物升级成功动画 * 播放植物图标的放大缩小动画,并在升级期间应用扫描效果材质,同时播放升级音效 * @param weaponIconNode 植物图标节点 */ public playWeaponUpgradeAnimation(weaponIconNode: Node): Promise { return new Promise((resolve) => { if (!weaponIconNode) { resolve(); return; } // 停止之前的动画,防止快速点击时动画冲突 Tween.stopAllByTarget(weaponIconNode); // 重置到原始缩放状态,确保动画从正确的状态开始 weaponIconNode.setScale(Vec3.ONE); // 保存原始缩放值 const originalScale = Vec3.ONE.clone(); let weaponSprite: Sprite = null; let originalMaterial: Material = null; console.log('[UpgradeAni] 开始武器升级动画,weaponSpriteNode:', this.weaponSpriteNode); // 播放植物升级音效 Audio.playUISound('data/弹球音效/equipment level up finish'); // 使用装饰器引用的WeaponSprite节点,获取其Sprite组件并保存原始材质 if (this.weaponSpriteNode) { console.log('[UpgradeAni] 找到weaponSpriteNode,开始获取Sprite组件'); weaponSprite = this.weaponSpriteNode.getComponent(Sprite); if (weaponSprite) { console.log('[UpgradeAni] 找到Sprite组件,开始加载材质'); // 保存原始材质,优先保存customMaterial,如果没有则保存当前material originalMaterial = weaponSprite.customMaterial || weaponSprite.material; console.log('[UpgradeAni] 原始材质:', originalMaterial); // 加载并应用扫描效果材质 resources.load('shaders/scan-effect', Material, (err, scanMaterial) => { console.log('[UpgradeAni] 材质加载回调,err:', err, 'scanMaterial:', scanMaterial); if (!err && scanMaterial && weaponSprite) { weaponSprite.material = scanMaterial; console.log('[UpgradeAni] 应用扫描效果材质成功'); } else { console.warn('[UpgradeAni] 加载扫描效果材质失败:', err); } }); } else { console.warn('[UpgradeAni] weaponSpriteNode上没有找到Sprite组件'); } } else { console.warn('[UpgradeAni] weaponSpriteNode为null,请在编辑器中设置'); } // 创建缩放动画:放大到1.5倍再立即缩小回原始大小 const scaleAnimation = tween(weaponIconNode) .to(0.25, { scale: new Vec3(originalScale.x * 1.5, originalScale.y * 1.5, originalScale.z) }, { easing: 'sineOut' }) .to(0.25, { scale: originalScale }, { easing: 'sineIn' }) .call(() => { // 动画结束后恢复原始材质 if (weaponSprite && originalMaterial) { // 如果原始材质是customMaterial,则恢复customMaterial if (weaponSprite.customMaterial === originalMaterial) { weaponSprite.material = weaponSprite.customMaterial; } else { weaponSprite.material = originalMaterial; } console.log('[UpgradeAni] 恢复原始材质成功'); } else if (weaponSprite) { // 如果没有保存的原始材质,尝试恢复到customMaterial if (weaponSprite.customMaterial) { weaponSprite.material = weaponSprite.customMaterial; console.log('[UpgradeAni] 恢复到customMaterial'); } else { weaponSprite.material = null; console.log('[UpgradeAni] 恢复到默认材质'); } } resolve(); }); // 播放缩放动画 scaleAnimation.start(); }); } /** * 显示升级面板动画 */ public showPanel(): Promise { return new Promise((resolve) => { const panel = this.node; if (!panel) { resolve(); return; } // 确保面板激活 panel.active = true; // 停止之前的动画 Tween.stopAllByTarget(panel); // 设置初始状态:缩放为0 panel.setScale(Vec3.ZERO); // 播放弹出动画 tween(panel) .to(0.3, { scale: Vec3.ONE }, { easing: 'backOut' }) .call(() => { resolve(); }) .start(); }); } /** * 隐藏升级面板动画 */ public hidePanel(): Promise { return new Promise((resolve) => { const panel = this.node; if (!panel) { resolve(); return; } // 停止之前的动画 Tween.stopAllByTarget(panel); // 播放缩小动画 tween(panel) .to(0.2, { scale: Vec3.ZERO }, { easing: 'backIn' }) .call(() => { // 动画结束后隐藏面板 panel.active = false; resolve(); }) .start(); }); } /** * 立即隐藏面板(无动画) */ public hidePanelImmediate(): void { const panel = this.node; if (panel) { // 停止所有动画 Tween.stopAllByTarget(panel); // 立即隐藏 panel.active = false; panel.setScale(Vec3.ONE); } } }