import { _decorator, Component, director, Label, Node, sys, Tween, tween, UITransform, Vec3 } from 'cc'; import { BattlePerformance } from './BattlePerformance'; const { ccclass, property } = _decorator; /** iOS 微信:单帧内允许创建的伤害飘字上限(含 Label.string + tween) */ let _wxIosHurtFloatFrame = -1; let _wxIosHurtFloatCount = 0; /** * 在创建飘字节点之前调用。非 iOS 微信始终返回 true。 * iOS 微信小游戏按帧限流,避免多段伤害同时触发时 Label/Tween 把主线程打满。 */ export function acquireWeChatIosHurtFloatSpawn(): boolean { if (!BattlePerformance.isWeChatIos()) { return true; } const max = BattlePerformance.hurtFloatMaxPerFrame(); const f = director.getTotalFrames(); if (f !== _wxIosHurtFloatFrame) { _wxIosHurtFloatFrame = f; _wxIosHurtFloatCount = 0; } if (_wxIosHurtFloatCount >= max) { return false; } _wxIosHurtFloatCount++; return true; } @ccclass('HurtScore') export class HurtScore extends Component { scoreLabel: Label = null protected onDisable(): void { // 节点回收到对象池后,可能仍有 scheduleOnce 回调挂着,需主动清理 this.unscheduleAllCallbacks(); Tween.stopAllByTarget(this.node); } protected onLoad(): void { this.scoreLabel = this.node.getComponent(Label) } /**显示伤害值 */ showHurtNum(hurtNum: number, isCrit: boolean, bRateAtk: boolean) { // 避免重复触发导致旧定时器回调仍在执行 this.unscheduleAllCallbacks(); Tween.stopAllByTarget(this.node); if (!this.scoreLabel.isValid) { return } let numStr = '' if (hurtNum >= 1000000) { numStr = `${Math.floor(hurtNum / 100000) / 10}M` } else if (hurtNum >= 1000) { numStr = `${Math.floor(hurtNum / 100) / 10}K` } else { numStr = `${Math.floor(hurtNum)}` } this.scoreLabel.string = `-${numStr}` let node = this.scoreLabel.node if (bRateAtk) { tween(node) .set({ opacity: 255 }) .to(0.1, { scale: new Vec3(2, 2, 2) }) .to(0.25, { scale: new Vec3(1, 1, 1) }) .to(0.12, { opacity: 0 }) .call(() => { gg.res.putNode(this.node) }) .start() this.scheduleOnce(() => { let width = this.scoreLabel.node.getComponent(UITransform).width if (this.node.getChildByName('底')) { this.node.getChildByName('底').getComponent(UITransform).width = width } }) } else { if (isCrit) { tween(node) .set({ opacity: 255 }) .to(0.1, { scale: new Vec3(1.8, 1.8, 1.8) }) .to(0.25, { scale: new Vec3(1, 1, 1) }) .to(0.12, { opacity: 0 }) .call(() => { gg.res.putNode(this.node) }) .start() this.scheduleOnce(() => { let width = this.scoreLabel.node.getComponent(UITransform).width if (this.node.getChildByName('暴')) { this.node.getChildByName('暴').position = new Vec3(width / 2 + 2, 32, 0) } }) } else { let pos = this.node.position.clone() tween(node) .set({ opacity: 255 }) .to(0.1, { scale: new Vec3(1, 1, 1) }) .to(0.5, { opacity: 0, position: new Vec3(pos.x, pos.y + 100, 0) }) .call(() => { gg.res.putNode(this.node) }) .start() } } } }