refactor(ui): 重构英雄信息面板组件,提取通用逻辑
- 将 HInfoComp 重构为独立组件,封装标签查找与数据绑定逻辑 - 在 MissionCardComp 中使用 HInfoComp 替代直接操作 Label 组件 - 移除冗余的 findNodeByPath 和 resolvePanelLabel 方法 - 通过 isModelAlive 方法统一检查模型有效性
This commit is contained in:
@@ -8,6 +8,7 @@ import { smc } from "../common/SingletonModuleComp";
|
||||
import { CardComp } from "./CardComp";
|
||||
import { oops } from "db://oops-framework/core/Oops";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { HInfoComp } from "./HInfoComp";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -54,8 +55,7 @@ export class MissionCardComp extends CCComp {
|
||||
private heroInfoItems: Map<number, {
|
||||
node: Node,
|
||||
model: HeroAttrsComp,
|
||||
apLabel: Label | null,
|
||||
hpLabel: Label | null
|
||||
comp: HInfoComp
|
||||
}> = new Map();
|
||||
onLoad() {
|
||||
/** 绑定事件 -> 缓存子控制器 -> 初始化UI状态 */
|
||||
@@ -372,18 +372,24 @@ export class MissionCardComp extends CCComp {
|
||||
const current = this.heroInfoItems.get(eid);
|
||||
if (current) {
|
||||
current.model = model;
|
||||
current.comp.bindData(eid, model);
|
||||
this.updateHeroInfoPanel(current);
|
||||
return;
|
||||
}
|
||||
const node = instantiate(this.hero_info_prefab);
|
||||
node.parent = this.hero_info_node;
|
||||
node.active = true;
|
||||
const comp = node.getComponent(HInfoComp);
|
||||
if (!comp) {
|
||||
node.destroy();
|
||||
return;
|
||||
}
|
||||
const item = {
|
||||
node,
|
||||
model,
|
||||
apLabel: this.resolvePanelLabel(node, [["ap", "val"]]),
|
||||
hpLabel: this.resolvePanelLabel(node, [["hp", "val"]])
|
||||
comp
|
||||
};
|
||||
comp.bindData(eid, model);
|
||||
this.heroInfoItems.set(eid, item);
|
||||
this.relayoutHeroInfoPanels();
|
||||
this.updateHeroInfoPanel(item);
|
||||
@@ -396,8 +402,7 @@ export class MissionCardComp extends CCComp {
|
||||
removeKeys.push(eid);
|
||||
return;
|
||||
}
|
||||
const ent = (item.model as any)?.ent;
|
||||
if (!ent) {
|
||||
if (!item.comp.isModelAlive()) {
|
||||
if (item.node.isValid) item.node.destroy();
|
||||
removeKeys.push(eid);
|
||||
return;
|
||||
@@ -415,11 +420,9 @@ export class MissionCardComp extends CCComp {
|
||||
private updateHeroInfoPanel(item: {
|
||||
node: Node,
|
||||
model: HeroAttrsComp,
|
||||
apLabel: Label | null,
|
||||
hpLabel: Label | null
|
||||
comp: HInfoComp
|
||||
}) {
|
||||
if (item.apLabel) item.apLabel.string = `${Math.max(0, Math.floor(item.model.ap ?? 0))}`;
|
||||
if (item.hpLabel) item.hpLabel.string = `${Math.max(0, Math.floor(item.model.hp_max ?? 0))}`;
|
||||
item.comp.refresh();
|
||||
}
|
||||
|
||||
private relayoutHeroInfoPanels() {
|
||||
@@ -448,25 +451,6 @@ export class MissionCardComp extends CCComp {
|
||||
this.heroInfoSyncTimer = 0;
|
||||
}
|
||||
|
||||
private resolvePanelLabel(root: Node, paths: string[][]): Label | null {
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
const node = this.findNodeByPath(root, paths[i]);
|
||||
if (!node) continue;
|
||||
const label = node.getComponent(Label) || node.getComponentInChildren(Label);
|
||||
if (label) return label;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private findNodeByPath(root: Node, path: string[]): Node | null {
|
||||
let current: Node | null = root;
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
current = current?.getChildByName(path[i]) ?? null;
|
||||
if (!current) return null;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
||||
reset() {
|
||||
this.clearHeroInfoPanels();
|
||||
|
||||
Reference in New Issue
Block a user