import { _decorator, Component, Node, Tween, tween,Vec3 } from 'cc'; const { ccclass, property } = _decorator; /** * 升级面板动画控制器 * 负责管理升级面板的显示和隐藏动画 */ @ccclass('UpgradeAni') export class UpgradeAni extends Component { /** * 显示面板动画 * 面板从小到大的缩放动画,从屏幕中央弹出 */ public showPanel(): Promise { return new Promise((resolve) => { // 设置初始状态:缩小到0,位置居中 this.node.setScale(Vec3.ZERO); this.node.setPosition(0, 0, 0); // 确保面板在屏幕正中间 this.node.active = true; // 缩放动画:从0放大到1 tween(this.node) .to(0.3, { scale: new Vec3(1, 1, 1) }, { easing: 'backOut' // 使用回弹缓动效果 }) .call(() => { resolve(); }) .start(); }); } /** * 隐藏面板动画 * 面板从大到小的缩放动画 */ public hidePanel(): Promise { return new Promise((resolve) => { // 缩放动画:从1缩小到0 tween(this.node) .to(0.2, { scale: Vec3.ZERO }, { easing: 'backIn' // 使用回弹缓动效果 }) .call(() => { this.node.active = false; resolve(); }) .start(); }); } /** * 立即隐藏面板(无动画) */ public hidePanelImmediate(): void { this.node.setScale(Vec3.ZERO); this.node.active = false; } /** * 立即显示面板(无动画) */ public showPanelImmediate(): void { this.node.setScale(Vec3.ONE); this.node.setPosition(0, 0, 0); // 确保面板在屏幕正中间 this.node.active = true; } /** * 武器升级成功动画 * 播放武器图标的放大缩小动画 * @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(); // 创建缩放动画:放大到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' }); // 只播放缩放动画 scaleAnimation.call(() => resolve()).start(); }); } /** * UP图标提示动画 * 播放缩小到0.7倍再放大到原来大小的重复动画,直到条件不满足为止 * @param upIconNode UP图标节点 * @param checkCondition 检查条件的回调函数,返回false时停止动画 */ public playUpIconAnimation(upIconNode: Node, checkCondition?: () => boolean): void { if (!upIconNode) return; // 停止之前的动画 Tween.stopAllByTarget(upIconNode); // 保存原始缩放值 const originalScale = upIconNode.scale.clone(); // 如果没有提供检查条件,使用默认的无限重复动画 if (!checkCondition) { const scaleAnimation = tween(upIconNode) .to(0.5, { scale: new Vec3(originalScale.x * 0.7, originalScale.y * 0.7, originalScale.z) }, { easing: 'sineInOut' }) .to(0.5, { scale: originalScale }, { easing: 'sineInOut' }) .repeatForever(); // 无限重复 scaleAnimation.start(); return; } // 带条件检查的动画循环 const playAnimationCycle = () => { // 在每次动画循环开始前检查条件 if (!checkCondition()) { // 条件不满足,停止动画并恢复原始缩放 this.stopUpIconAnimation(upIconNode); return; } // 创建一次完整的缩放动画循环 const scaleAnimation = tween(upIconNode) .to(0.5, { scale: new Vec3(originalScale.x * 0.7, originalScale.y * 0.7, originalScale.z) }, { easing: 'sineInOut' }) .to(0.5, { scale: originalScale }, { easing: 'sineInOut' }) .call(() => { // 一次循环完成后,递归调用下一次循环 playAnimationCycle(); }); scaleAnimation.start(); }; // 开始第一次动画循环 playAnimationCycle(); } /** * 停止UP图标动画 * @param upIconNode UP图标节点 */ public stopUpIconAnimation(upIconNode: Node): void { if (!upIconNode) return; // 停止所有动画 Tween.stopAllByTarget(upIconNode); // 恢复原始缩放 upIconNode.setScale(Vec3.ONE); } }