refactor(map): 重构英雄信息弹窗逻辑,移除oops.gui依赖
1. 将英雄信息弹窗从框架GUI系统改为同步实例化管理 2. 由HeroBoxComp接管弹窗的创建和销毁时机 3. 删除冗余的UIID配置和弹窗参数接口 4. 调整弹窗关闭逻辑,避免缓存节点带来的竞态问题
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* 职责:
|
||||
* 1. 同步显示一个已登场英雄的基础信息(图标 / 名称 / 等级 / AP / HP)。
|
||||
* 2. 长按英雄盒弹出信息面板(UIID.HeroMore → more.prefab),展示次级属性与技能描述。
|
||||
* 2. 长按英雄盒同步实例化信息面板(more.prefab),展示次级属性与技能描述;放开手指销毁。
|
||||
* 3. 由 MissionCardComp 实例化到 herosBoxNode 下,最多 3 个,与场上英雄一一对应。
|
||||
* 4. 英雄卖出 / 死亡后槽位保留,通过 applyEmpty() 显示为空英雄信息。
|
||||
*
|
||||
@@ -13,7 +13,7 @@
|
||||
* - HeroInfo(heroSet)—— 英雄静态配置
|
||||
*/
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { _decorator, Node, Sprite, Label, resources, AnimationClip, SpriteFrame, NodeEventType, EventTouch, Tween, tween, Vec3, Color } from "cc";
|
||||
import { _decorator, Node, Sprite, Label, resources, AnimationClip, SpriteFrame, NodeEventType, EventTouch, Tween, tween, Vec3, Color, Prefab, instantiate, director, find } 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 { oops } from "db://oops-framework/core/Oops";
|
||||
@@ -25,6 +25,7 @@ import { FacSet, FightSet, getLvColor } from "../common/config/GameSet";
|
||||
import { buildSkillDesc, ISkillDescSource } from "../common/config/HeroSkillDesc";
|
||||
import { MissionEconomy } from "./MissionEconomy";
|
||||
import { UIID } from "../common/config/GameUIConfig";
|
||||
import { HeroMoreCom } from "./HeroMoreCom";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -91,6 +92,10 @@ export class HeroBoxComp extends CCComp {
|
||||
@property(Label)
|
||||
private hp_plus_label: Label = null;
|
||||
|
||||
/** 英雄信息弹窗预制体(长按英雄盒时同步实例化展示,绕开 oops.gui 异步加载) */
|
||||
@property(Prefab)
|
||||
private morePrefab: Prefab = null;
|
||||
|
||||
// ======================== 运行时状态 ========================
|
||||
|
||||
/** 绑定的英雄实体 ID(0 表示空槽位) */
|
||||
@@ -102,6 +107,9 @@ export class HeroBoxComp extends CCComp {
|
||||
/** 当前显示的英雄 UUID(避免相同 UUID 重复加载动画) */
|
||||
private iconHeroUuid: number = 0;
|
||||
|
||||
/** 当前已弹出的英雄信息面板节点(null 表示未弹出) */
|
||||
private moreNode: Node | null = null;
|
||||
|
||||
/** 长按判定:当前按下触摸 ID(-1 表示无) */
|
||||
private longPressTouchId: number = -1;
|
||||
/** 长按判定:按下起点 UI 坐标 */
|
||||
@@ -115,7 +123,7 @@ export class HeroBoxComp extends CCComp {
|
||||
// ======================== 生命周期 ========================
|
||||
|
||||
onLoad() {
|
||||
// 长按英雄盒任意区域弹出信息面板(UIID.HeroMore → more.prefab);出售/升级按钮上的触摸不触发
|
||||
// 长按英雄盒任意区域实例化信息面板(more.prefab);出售/升级按钮上的触摸不触发
|
||||
this.node.on(NodeEventType.TOUCH_START, this.onBoxTouchStart, this);
|
||||
this.node.on(NodeEventType.TOUCH_MOVE, this.onBoxTouchMove, this);
|
||||
this.node.on(NodeEventType.TOUCH_END, this.onBoxTouchEnd, this);
|
||||
@@ -144,6 +152,8 @@ export class HeroBoxComp extends CCComp {
|
||||
if (this.upgrade_btn && this.upgrade_btn.isValid) {
|
||||
this.upgrade_btn.off(NodeEventType.TOUCH_END, this.onUpgradeHeroClick, this);
|
||||
}
|
||||
// 销毁时一并清理已弹出的信息面板
|
||||
this.closeMoreNode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -350,14 +360,16 @@ export class HeroBoxComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
/** 英雄盒抬起:取消未触发的长按判定 */
|
||||
/** 英雄盒抬起:取消未触发的长按判定;若长按已弹出信息面板则立即关闭 */
|
||||
private onBoxTouchEnd(event: EventTouch) {
|
||||
if (this.longPressTouchId < 0) return;
|
||||
if ((event.touch?.getID() ?? -1) !== this.longPressTouchId) return;
|
||||
this.cancelLongPress();
|
||||
// 直接销毁已弹出的信息面板(同步 destroy,无竞态)
|
||||
this.closeMoreNode();
|
||||
}
|
||||
|
||||
/** 英雄盒触摸被系统打断:取消长按判定 */
|
||||
/** 英雄盒触摸被系统打断:取消长按判定;若已弹窗则一并关闭 */
|
||||
private onBoxTouchCancel(event: EventTouch) {
|
||||
this.onBoxTouchEnd(event);
|
||||
}
|
||||
@@ -368,12 +380,32 @@ export class HeroBoxComp extends CCComp {
|
||||
this.unschedule(this.onLongPressFired);
|
||||
}
|
||||
|
||||
/** 长按触发:弹出英雄信息面板(more.prefab,展示次级属性与技能描述) */
|
||||
/** 长按触发:同步实例化英雄信息面板(more.prefab,展示次级属性与技能描述) */
|
||||
private onLongPressFired() {
|
||||
this.longPressTouchId = -1;
|
||||
// 不重置 longPressTouchId:保留以便 onBoxTouchEnd 能识别同一触摸并销毁弹窗
|
||||
if (!this.hasHero || !(this.model as any)?.ent) return;
|
||||
if (!this.morePrefab) {
|
||||
mLogger.warn(true, "HeroBoxComp", "onLongPressFired morePrefab 未绑定,请在编辑器拖入 more.prefab");
|
||||
return;
|
||||
}
|
||||
oops.audio.playEffect("music/button");
|
||||
oops.gui.open(UIID.HeroMore, { eid: this.eid });
|
||||
// 同步实例化:避开 oops.gui 首次异步加载窗口期,确保放开时能立即 destroy
|
||||
this.closeMoreNode();
|
||||
this.moreNode = instantiate(this.morePrefab);
|
||||
// more.prefab 是全屏遮罩弹窗,必须挂到 Canvas 根节点,避免被英雄盒父节点的 Mask 裁剪或坐标系错位
|
||||
const canvas = find("Canvas") || director.getScene()?.getChildByName("Canvas");
|
||||
(canvas ?? this.node.parent)?.addChild(this.moreNode);
|
||||
// 整体上移 100 像素(弹窗相对英雄盒偏上展示)
|
||||
this.moreNode.setPosition(this.moreNode.position.x, this.moreNode.position.y + 100, this.moreNode.position.z);
|
||||
this.moreNode.getComponent(HeroMoreCom)?.init(this.eid);
|
||||
}
|
||||
|
||||
/** 关闭并清理已弹出的英雄信息面板(同步 destroy) */
|
||||
private closeMoreNode() {
|
||||
if (this.moreNode && this.moreNode.isValid) {
|
||||
this.moreNode.destroy();
|
||||
}
|
||||
this.moreNode = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user