Files
pixelheros/assets/script/game/map/HInfoComp.ts
panw 80bf8efc30 refactor(ui): 重构英雄信息面板组件,提取通用逻辑
- 将 HInfoComp 重构为独立组件,封装标签查找与数据绑定逻辑
- 在 MissionCardComp 中使用 HInfoComp 替代直接操作 Label 组件
- 移除冗余的 findNodeByPath 和 resolvePanelLabel 方法
- 通过 isModelAlive 方法统一检查模型有效性
2026-03-25 17:26:51 +08:00

67 lines
2.0 KiB
TypeScript

import { _decorator, Label, Node } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
const { ccclass } = _decorator;
/** 视图层对象 */
@ccclass('HInfoComp')
@ecs.register('HInfoComp', false)
export class HInfoComp extends CCComp {
private eid: number = 0;
private model: HeroAttrsComp | null = null;
private apLabel: Label | null = null;
private hpLabel: Label | null = null;
onLoad() {
this.cacheLabels();
}
bindData(eid: number, model: HeroAttrsComp) {
this.eid = eid;
this.model = model;
this.cacheLabels();
this.refresh();
}
refresh() {
if (!this.model) return;
if (this.apLabel) {
this.apLabel.string = `${Math.max(0, Math.floor(this.model.ap ?? 0))}`;
}
if (this.hpLabel) {
this.hpLabel.string = `${Math.max(0, Math.floor(this.model.hp_max ?? 0))}`;
}
}
isModelAlive(): boolean {
return !!(this.model as any)?.ent;
}
private cacheLabels() {
if (!this.apLabel) {
this.apLabel = this.findLabelByPath(["ap", "val"]);
}
if (!this.hpLabel) {
this.hpLabel = this.findLabelByPath(["hp", "val"]);
}
}
private findLabelByPath(path: string[]): Label | null {
let current: Node | null = this.node;
for (let i = 0; i < path.length; i++) {
current = current?.getChildByName(path[i]) ?? null;
if (!current) return null;
}
return current.getComponent(Label) || current.getComponentInChildren(Label);
}
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
reset() {
this.model = null;
this.eid = 0;
this.node.destroy();
}
}