Files
heros/assets/script/game/damage/DamageShowSystem.ts

96 lines
3.0 KiB
TypeScript

import { _decorator, NodePool, Node, Label, Color, tween, Vec3, instantiate, Prefab, resources } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { DamageResult } from "./DamageComp";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { DamageText } from "./DamageText";
@ecs.register('DamageShowSystem')
export class DamageShowSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate{
private _pool: NodePool = new NodePool();
private _timers: Set<number> = new Set();
private _prefab: Prefab | null = null;
init() {
// 使用原生资源加载
resources.load("game/skills/damageText", Prefab, (err, prefab) => {
if (err) {
console.error("预制体加载失败:", err);
return;
}
this._prefab = prefab;
console.log("预制体加载成功:", this._prefab);
// 初始化对象池
for (let i = 0; i < 10; i++) {
const node = instantiate(this._prefab!);
this._pool.put(node);
}
});
}
filter(): ecs.IMatcher {
return ecs.allOf(DamageResult);
}
update(e: ecs.Entity) {
const res = e.get(DamageResult);
this.scheduleShow(res);
e.remove(DamageResult);
}
private scheduleShow(res: DamageResult) {
const timer = setTimeout(() => {
let node = this._pool.get();
if (!node || !node.isValid) {
node = instantiate(this._prefab);
}
const damageText = node.getComponent(DamageText);
if (!damageText) {
console.error("Damage text prefab must have DamageText component!");
return;
}
this.setupText(node, res);
this.playAnimation(node, res.position);
this._timers.delete(timer);
}, res.delay * 1000);
this._timers.add(timer);
}
private setupText(node: Node, res: DamageResult) {
const damageText = node.getComponent(DamageText)!;
const label = damageText.label;
if (res.isDodged) {
label.string = "Miss";
label.color = Color.GRAY;
return;
}
label.string = Math.round(res.value).toString();
label.color = res.isCrit ? Color.RED : Color.WHITE;
damageText.playEffect(res.isCrit);
}
private playAnimation(node: Node, position: Vec3) {
node.setPosition(position);
tween(node)
.by(0.5, { position: new Vec3(0, 100, 0) })
.call(() => {
if (this._pool.size() < 20) { // 控制最大缓存数量
this._pool.put(node);
} else {
node.destroy();
}
})
.start();
}
onDestroy() {
this._timers.forEach(clearTimeout);
this._pool.clear();
}
}