refactor(map,gui): 重构卡牌和英雄信息弹窗逻辑,新增静态预览模式
1. 移除卡牌的长按放大逻辑,改为长按直接打开英雄静态预览面板 2. 重构HInfoComp,新增静态预览模式支持,无需绑定实体数据 3. 调整card和hnode预制体的缩放参数 4. 简化卡牌UI的尺寸和位置计算逻辑,移除放大状态的额外处理
This commit is contained in:
@@ -81,6 +81,12 @@ export class HInfoComp extends CCComp {
|
||||
private eid: number = 0;
|
||||
/** 绑定的英雄属性数据模型引用 */
|
||||
private model: HeroAttrsComp | null = null;
|
||||
/** 是否为静态预览模式(卡牌点击查看,非场上英雄) */
|
||||
private isPreview: boolean = false;
|
||||
/** 静态预览数据 */
|
||||
private previewUuid: number = 0;
|
||||
private previewLv: number = 1;
|
||||
private previewPoolLv: number = 1;
|
||||
/** 英雄名字标签缓存引用 */
|
||||
private nameLabel: Label | null = null;
|
||||
/** AP 标签缓存引用 */
|
||||
@@ -103,7 +109,11 @@ export class HInfoComp extends CCComp {
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
onAdded(args: { eid: number }) {
|
||||
onAdded(args: { eid?: number; heroUuid?: number; heroLv?: number; poolLv?: number }) {
|
||||
if (args?.heroUuid) {
|
||||
this.bindPreviewData(args.heroUuid, args.heroLv ?? 1, args.poolLv ?? 1);
|
||||
return;
|
||||
}
|
||||
const eid = args?.eid ?? 0;
|
||||
if (!eid) return;
|
||||
|
||||
@@ -122,11 +132,55 @@ export class HInfoComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态预览模式刷新:从 HeroInfo 配置读取初始数据。
|
||||
*/
|
||||
private refreshPreview() {
|
||||
const heroUuid = this.previewUuid;
|
||||
const hero = HeroInfo[heroUuid];
|
||||
if (!hero) return;
|
||||
const heroLv = Math.max(1, this.previewLv);
|
||||
|
||||
if (this.lv_node) {
|
||||
this.lv_node.string = `Lv.${heroLv}`;
|
||||
this.lv_node.color = getLvColor(heroLv);
|
||||
}
|
||||
|
||||
if (this.pool_lvnode) {
|
||||
const poolLvStr = `lv${this.previewPoolLv}`;
|
||||
this.pool_lvnode.children.forEach(child => {
|
||||
child.active = (child.name === poolLvStr);
|
||||
});
|
||||
}
|
||||
|
||||
if (heroUuid !== this.iconHeroUuid) {
|
||||
this.iconHeroUuid = heroUuid;
|
||||
this.iconVisualToken += 1;
|
||||
this.updateHeroAnimation(this.icon_node, heroUuid, this.iconVisualToken);
|
||||
}
|
||||
|
||||
if (this.nameLabel) {
|
||||
this.nameLabel.string = hero.name ?? "";
|
||||
}
|
||||
|
||||
if (this.apLabel) {
|
||||
const ap = Math.max(0, Math.floor((hero.ap ?? 0) * heroLv));
|
||||
this.apLabel.string = `${ap}`;
|
||||
if (this.apPlusLabel) this.apPlusLabel.node.active = false;
|
||||
}
|
||||
if (this.hpLabel) {
|
||||
const hp = Math.max(0, Math.floor((hero.hp ?? 0) * heroLv));
|
||||
this.hpLabel.string = `${hp}`;
|
||||
if (this.hpPlusLabel) this.hpPlusLabel.node.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** 是否正在关闭中,防止重复调用 remove */
|
||||
private isClosing: boolean = false;
|
||||
|
||||
update(dt: number) {
|
||||
if (this.isClosing) return;
|
||||
if (this.isPreview) return;
|
||||
if (!this.isModelAlive()) {
|
||||
this.isClosing = true;
|
||||
oops.gui.remove(UIID.HInfo);
|
||||
@@ -148,6 +202,24 @@ export class HInfoComp extends CCComp {
|
||||
bindData(eid: number, model: HeroAttrsComp) {
|
||||
this.eid = eid;
|
||||
this.model = model;
|
||||
this.isPreview = false;
|
||||
if (this.sell_node) this.sell_node.active = true;
|
||||
if (this.close_node) this.close_node.active = true;
|
||||
this.cacheLabels();
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定静态预览数据(卡牌点击查看)。
|
||||
* 通过 HeroInfo 配置 × 等级计算初始值,不绑定 ECS 实体。
|
||||
*/
|
||||
bindPreviewData(heroUuid: number, heroLv: number, poolLv: number) {
|
||||
this.isPreview = true;
|
||||
this.previewUuid = heroUuid;
|
||||
this.previewLv = heroLv;
|
||||
this.previewPoolLv = poolLv;
|
||||
if (this.sell_node) this.sell_node.active = false;
|
||||
if (this.close_node) this.close_node.active = false;
|
||||
this.cacheLabels();
|
||||
this.refresh();
|
||||
}
|
||||
@@ -159,6 +231,10 @@ export class HInfoComp extends CCComp {
|
||||
* 3. 更新 AP / HP 数值标签。
|
||||
*/
|
||||
refresh() {
|
||||
if (this.isPreview) {
|
||||
this.refreshPreview();
|
||||
return;
|
||||
}
|
||||
if (!this.model) return;
|
||||
|
||||
// ---- 卡牌等级显示 ----
|
||||
@@ -287,9 +363,11 @@ export class HInfoComp extends CCComp {
|
||||
const path = `game/heros/hero/${hero.path}/idle`;
|
||||
resources.load(path, AnimationClip, (err, clip) => {
|
||||
if (err || !clip) return;
|
||||
// 竞态保护
|
||||
if (token !== this.iconVisualToken || !this.model || this.model.hero_uuid !== uuid) {
|
||||
return;
|
||||
if (token !== this.iconVisualToken) return;
|
||||
if (this.isPreview) {
|
||||
if (this.previewUuid !== uuid) return;
|
||||
} else {
|
||||
if (!this.model || this.model.hero_uuid !== uuid) return;
|
||||
}
|
||||
this.clearAnimationClips(anim);
|
||||
anim.addClip(clip);
|
||||
@@ -397,9 +475,9 @@ export class HInfoComp extends CCComp {
|
||||
this.iconHeroUuid = 0;
|
||||
this.model = null;
|
||||
this.eid = 0;
|
||||
// 弹窗节点的生命周期由 oops.gui 统一管理,此处不再主动销毁节点
|
||||
// if (this.node && this.node.isValid) {
|
||||
// this.node.destroy();
|
||||
// }
|
||||
this.isPreview = false;
|
||||
this.previewUuid = 0;
|
||||
this.previewLv = 1;
|
||||
this.previewPoolLv = 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user