feat: 新增英雄基础属性存档与UI属性加成显示
1. 新增base_ap和base_hp属性存储英雄原始基础攻防属性 2. 实现属性加成差值显示,展示当前属性与基础属性的差异 3. 重构英雄信息UI,新增名字、关闭按钮等节点绑定 4. 调整英雄预制体布局,适配新的UI展示需求 5. 补充战斗触发类型注释文档
This commit is contained in:
@@ -51,27 +51,44 @@ export class HInfoComp extends CCComp {
|
||||
/** 英雄 idle 动画图标节点 */
|
||||
@property(Node)
|
||||
icon_node=null!
|
||||
/** 出售按钮节点(预留,当前交互已注释) */
|
||||
/** 出售按钮节点 */
|
||||
@property(Node)
|
||||
sell_node=null!
|
||||
/** 普通品质边框 */
|
||||
|
||||
/** 关闭窗口按钮节点 */
|
||||
@property(Node)
|
||||
NF_node=null!
|
||||
close_node=null!
|
||||
|
||||
/** 英雄名字节点 */
|
||||
@property(Node)
|
||||
Name_node=null!
|
||||
/** 高品质边框 */
|
||||
@property(Node)
|
||||
HF_node=null!
|
||||
info_node=null!
|
||||
|
||||
@property(Node)
|
||||
lv_node=null!
|
||||
|
||||
@property(Node)
|
||||
ap_node=null!
|
||||
|
||||
@property(Node)
|
||||
hp_node=null!
|
||||
|
||||
/** 绑定的英雄 ECS 实体 ID */
|
||||
private eid: number = 0;
|
||||
/** 绑定的英雄属性数据模型引用 */
|
||||
private model: HeroAttrsComp | null = null;
|
||||
/** 英雄名字标签缓存引用 */
|
||||
private nameLabel: Label | null = null;
|
||||
/** AP 标签缓存引用 */
|
||||
private apLabel: Label | null = null;
|
||||
/** AP 加成标签缓存引用 */
|
||||
private apPlusLabel: Label | null = null;
|
||||
/** HP 标签缓存引用 */
|
||||
private hpLabel: Label | null = null;
|
||||
/** HP 加成标签缓存引用 */
|
||||
private hpPlusLabel: Label | null = null;
|
||||
/** 图标视觉令牌(异步加载竞态保护) */
|
||||
private iconVisualToken: number = 0;
|
||||
/** 当前显示的英雄 UUID(避免相同 UUID 重复加载动画) */
|
||||
@@ -161,12 +178,39 @@ export class HInfoComp extends CCComp {
|
||||
this.updateHeroAnimation(this.icon_node, heroUuid, this.iconVisualToken);
|
||||
}
|
||||
|
||||
// ---- 名字标签 ----
|
||||
if (this.nameLabel) {
|
||||
this.nameLabel.string = this.model.hero_name ?? "";
|
||||
}
|
||||
|
||||
// ---- 数值标签 ----
|
||||
if (this.apLabel) {
|
||||
this.apLabel.string = `${Math.max(0, Math.floor(this.model.ap ?? 0))}`;
|
||||
const currentAp = Math.max(0, Math.floor(this.model.ap ?? 0));
|
||||
const baseAp = Math.max(0, Math.floor(this.model.base_ap ?? 0));
|
||||
this.apLabel.string = `${currentAp}`;
|
||||
if (this.apPlusLabel) {
|
||||
const diff = currentAp - baseAp;
|
||||
if (diff !== 0) {
|
||||
this.apPlusLabel.string = diff > 0 ? `(+${diff})` : `(${diff})`;
|
||||
this.apPlusLabel.node.active = true;
|
||||
} else {
|
||||
this.apPlusLabel.node.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.hpLabel) {
|
||||
this.hpLabel.string = `${Math.max(0, Math.floor(this.model.hp_max ?? 0))}`;
|
||||
const currentHp = Math.max(0, Math.floor(this.model.hp_max ?? 0));
|
||||
const baseHp = Math.max(0, Math.floor(this.model.base_hp ?? 0));
|
||||
this.hpLabel.string = `${currentHp}`;
|
||||
if (this.hpPlusLabel) {
|
||||
const diff = currentHp - baseHp;
|
||||
if (diff !== 0) {
|
||||
this.hpPlusLabel.string = diff > 0 ? `(+${diff})` : `(${diff})`;
|
||||
this.hpPlusLabel.node.active = true;
|
||||
} else {
|
||||
this.hpPlusLabel.node.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,11 +226,16 @@ export class HInfoComp extends CCComp {
|
||||
|
||||
/** 缓存 AP / HP Label 引用,避免每次刷新都遍历节点树 */
|
||||
private cacheLabels() {
|
||||
if (!this.apLabel) {
|
||||
this.apLabel = this.findLabelByPath(["ap", "val"]);
|
||||
if (!this.nameLabel && this.Name_node) {
|
||||
this.nameLabel = this.Name_node.getComponent(Label) || this.Name_node.getComponentInChildren(Label);
|
||||
}
|
||||
if (!this.hpLabel) {
|
||||
this.hpLabel = this.findLabelByPath(["hp", "val"]);
|
||||
if (!this.apLabel && this.ap_node) {
|
||||
this.apLabel = this.ap_node.getChildByName("val")?.getComponent(Label) || null;
|
||||
this.apPlusLabel = this.ap_node.getChildByName("plus")?.getComponent(Label) || null;
|
||||
}
|
||||
if (!this.hpLabel && this.hp_node) {
|
||||
this.hpLabel = this.hp_node.getChildByName("val")?.getComponent(Label) || null;
|
||||
this.hpPlusLabel = this.hp_node.getChildByName("plus")?.getComponent(Label) || null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,16 +304,29 @@ export class HInfoComp extends CCComp {
|
||||
|
||||
private bindEvents() {
|
||||
this.sell_node?.on(Button.EventType.CLICK, this.onSellHero, this);
|
||||
this.node.on(NodeEventType.TOUCH_END, this.onOpenIBox, this);
|
||||
this.close_node?.on(Button.EventType.CLICK, this.onClosePanel, this);
|
||||
// this.node.on(NodeEventType.TOUCH_END, this.onOpenIBox, this);
|
||||
}
|
||||
|
||||
private unbindEvents() {
|
||||
if (this.sell_node && this.sell_node.isValid) {
|
||||
this.sell_node.off(Button.EventType.CLICK, this.onSellHero, this);
|
||||
}
|
||||
if (this.node && this.node.isValid) {
|
||||
this.node.off(NodeEventType.TOUCH_END, this.onOpenIBox, this);
|
||||
if (this.close_node && this.close_node.isValid) {
|
||||
this.close_node.off(Button.EventType.CLICK, this.onClosePanel, this);
|
||||
}
|
||||
// if (this.node && this.node.isValid) {
|
||||
// this.node.off(NodeEventType.TOUCH_END, this.onOpenIBox, this);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击关闭按钮时关闭英雄信息面板
|
||||
*/
|
||||
private onClosePanel() {
|
||||
if (this.isClosing) return;
|
||||
this.isClosing = true;
|
||||
oops.gui.remove(UIID.HInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user