You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.6 KiB
104 lines
3.6 KiB
import { assetManager, instantiate, Label, Node, Prefab, tween, Tween, UIOpacity, UITransform, Vec3 } from 'cc';
|
|
import { GBundle, GPath } from '../../game/ConfigRes';
|
|
import { UILayer } from '../../../mx/module/ui/UIManager';
|
|
|
|
const POWER_PREFAB_NAME = 'power';
|
|
const FLOAT_UP_PX = 80;
|
|
const FLOAT_DURATION_SEC = 1.2;
|
|
|
|
/**
|
|
* Battlebuff 体力增加飘字(comm/prefab/power,addNum 显示 +N)
|
|
*/
|
|
export class BattleBuffVigourFloatView {
|
|
/** 播放体力增加飘字 */
|
|
static play(amount: number, parent?: Node | null, worldPos?: Vec3 | null): void {
|
|
const delta = Math.max(0, Math.floor(Number(amount) || 0));
|
|
if (delta <= 0) return;
|
|
|
|
const mountParent = parent?.isValid ? parent : null;
|
|
if (!mountParent && !gg.ui) {
|
|
console.log('[BattleBuffVigourFloatView] UI 未就绪');
|
|
return;
|
|
}
|
|
|
|
const attach = (prefabNode: Node): void => {
|
|
BattleBuffVigourFloatView._setupNode(prefabNode, mountParent, worldPos, delta);
|
|
};
|
|
|
|
const cachedPrefab = gg.res.getRes<Prefab>(POWER_PREFAB_NAME, GPath.Prefab, GBundle.Comm, Prefab);
|
|
if (cachedPrefab) {
|
|
attach(instantiate(cachedPrefab));
|
|
return;
|
|
}
|
|
|
|
const bundle = assetManager.getBundle(GBundle.Comm);
|
|
if (!bundle) {
|
|
console.log('[BattleBuffVigourFloatView] comm bundle 未加载');
|
|
return;
|
|
}
|
|
const full = `${GPath.Prefab}${POWER_PREFAB_NAME}`;
|
|
const loadedPrefab = bundle.get(full, Prefab);
|
|
if (loadedPrefab) {
|
|
attach(instantiate(loadedPrefab));
|
|
return;
|
|
}
|
|
bundle.load(full, Prefab, (err, loaded) => {
|
|
if (err || !loaded) {
|
|
if (err) console.log('[BattleBuffVigourFloatView] power 预制体加载失败', String(err));
|
|
return;
|
|
}
|
|
attach(instantiate(loaded));
|
|
});
|
|
}
|
|
|
|
private static _setupNode(node: Node, parent: Node | null, worldPos: Vec3 | null | undefined, delta: number): void {
|
|
if (parent?.isValid) {
|
|
node.parent = parent;
|
|
} else {
|
|
gg.ui.showNode(node, UILayer.Anim);
|
|
}
|
|
node.active = true;
|
|
|
|
const layerParent = node.parent;
|
|
if (!layerParent?.isValid) {
|
|
node.destroy();
|
|
return;
|
|
}
|
|
|
|
const addNum = node.getChildByName('addNum')?.getComponent(Label);
|
|
if (!addNum) {
|
|
console.log('[BattleBuffVigourFloatView] addNum 节点缺失');
|
|
node.destroy();
|
|
return;
|
|
}
|
|
addNum.string = `+${delta}`;
|
|
|
|
const local = BattleBuffVigourFloatView._resolveLocalPos(layerParent, worldPos);
|
|
node.setPosition(local.x, local.y, local.z);
|
|
|
|
const opacity = node.getComponent(UIOpacity) ?? node.addComponent(UIOpacity);
|
|
opacity.opacity = 255;
|
|
Tween.stopAllByTarget(node);
|
|
Tween.stopAllByTarget(opacity);
|
|
|
|
const endY = local.y + FLOAT_UP_PX;
|
|
tween(node)
|
|
.to(FLOAT_DURATION_SEC, { position: new Vec3(local.x, endY, local.z) }, { easing: 'cubicOut' })
|
|
.call(() => {
|
|
if (node.isValid) node.destroy();
|
|
})
|
|
.start();
|
|
tween(opacity)
|
|
.delay(FLOAT_DURATION_SEC * 0.35)
|
|
.to(FLOAT_DURATION_SEC * 0.65, { opacity: 0 })
|
|
.start();
|
|
}
|
|
|
|
private static _resolveLocalPos(parent: Node, worldPos?: Vec3 | null): Vec3 {
|
|
const ut = parent.getComponent(UITransform);
|
|
if (worldPos && ut) {
|
|
return ut.convertToNodeSpaceAR(worldPos);
|
|
}
|
|
return new Vec3(0, 0, 0);
|
|
}
|
|
}
|
|
|