import { _decorator, Button, Component, Label, Node, Prefab, sp, Sprite, Tween, tween, UIOpacity, v3 } from 'cc'; import { NodePoolManager } from '../../../Loading/scripts/manager/NodePoolManager'; import { gold2cash } from '../../../Loading/scripts/comm'; import { AudioManager } from '../../../Loading/scripts/manager/AudioManager'; const { ccclass, property } = _decorator; @ccclass('TotalWin') export class TotalWin extends Component { @property(Prefab) totalWinUiPre: Prefab = null; totalWinUINode: Node = null; btnNode: Node = null; totalWinSpine: sp.Skeleton | null = null; NumNodeOpacityCom: UIOpacity | null = null; scoreLabel: Label | null = null; // 分数节点 currentWinScore: number = 0; // 当前显示赢分 isScrolling: boolean = true; // 分数是否在滚动 scrollTime: number = 2; // 不点击的情况下分数滚动所花时间 isSkipByTouch: boolean = false; winScore: number = 0; // 最终赢分 btn: Button | null = null; closeCallBack: (() => void) | null = null; show(winScore: number, closeCallBack: (() => void) | null = null) { this.totalWinUINode = NodePoolManager.instance.getNodeFromPoolStatic('totalWinUI', this.totalWinUiPre); this.totalWinSpine = this.totalWinUINode.getChildByName('spine').getComponent(sp.Skeleton); let numNode = this.totalWinSpine.node.getChildByName('NumNode'); this.NumNodeOpacityCom = numNode.getComponent(UIOpacity); this.NumNodeOpacityCom.opacity = 255; this.scoreLabel = numNode.getChildByName('Label').getComponent(Label); Tween.stopAllByTarget(this.NumNodeOpacityCom.node); this.isScrolling = true; this.btnNode = this.totalWinSpine.node.getChildByName('BtnNode'); this.btn = this.btnNode.getChildByName('btnCollect').getComponent(Button); this.btn.node.on(Button.EventType.CLICK, this.onClose, this); this.totalWinUINode.getChildByName('spine').on(Node.EventType.TOUCH_START, this.onTouch, this); this.scoreLabel.string = '0' this.winScore = winScore; this.btnNode.active = false; this.node.addChild(this.totalWinUINode); this.playAnimation(); AudioManager.instance.playSFX('Total_Settle_Sound'); this.closeCallBack = closeCallBack; this.startScoreAni() } startScoreAni() { // 修改这里的滚动逻辑 let startScore = this.currentWinScore; let startTime = 0; this.isScrolling = true; let updateScore = function (dt: number) { if (!this.isScrolling) return; startTime += dt; let progress = Math.min(startTime / this.scrollTime, 1); let easedProgress = this.easeOutQuad(progress); this.currentWinScore = startScore + (this.winScore - startScore) * easedProgress; this.updateScoreLabel(); if (progress >= 1) { this.currentWinScore = this.winScore; // 确保最终数值精确 this.updateScoreLabel(); this.btnNode.active = true; this.unschedule(updateScore); } }.bind(this); this.schedule(updateScore, 0.01); } // 添加缓动函数 easeOutQuad(t: number): number { return t * (2 - t); } updateScoreLabel() { if (this.scoreLabel) this.scoreLabel.string = gold2cash(this.currentWinScore); } async onTouch() { if (!this.totalWinUINode) return; // 添加节点存在检查 if (this.isScrolling) { this.isSkipByTouch = true; // 立即完成当前动画 this.isScrolling = false; this.unscheduleAllCallbacks(); // 直接设置为最终分数 this.currentWinScore = this.winScore; this.updateScoreLabel(); this.btnNode.active = true; AudioManager.instance.stopAllSFX() AudioManager.instance.playSFX('Total_Settle_End_Sound'); } } playAnimation() { this.totalWinSpine.clearTracks(); this.totalWinSpine.setAnimation(0, 'in', false); this.totalWinSpine.setCompleteListener(() => { this.totalWinSpine.setAnimation(0, 'loop', true); }) } // 加入回调 onClose() { this.btn.node.off(Button.EventType.CLICK, this.onClose, this); this.totalWinUINode.getChildByName('spine').off(Node.EventType.TOUCH_START, this.onTouch, this); this.fadeOutScoreLabel(1.7, 0.6); this.btnNode.active = false; this.unscheduleAllCallbacks(); this.totalWinSpine.clearTracks(); this.totalWinSpine.setAnimation(0, 'out', true); this.totalWinSpine.setCompleteListener(() => { this.totalWinUINode.removeFromParent(); NodePoolManager.instance.putNodeToPool('totalWinUI', this.totalWinUINode); this.closeCallBack && this.closeCallBack(); }) } fadeOutScoreLabel(delay: number, duration: number) { // 先停止可能正在进行的动画 Tween.stopAllByTarget(this.NumNodeOpacityCom.node); // 确保标签是可见的 this.NumNodeOpacityCom.opacity = 255; // 创建并执行渐隐动画 tween(this.NumNodeOpacityCom) .delay(delay) .to(duration, { opacity: 0 }) .start(); } }