refactor(map): 重构任务卡牌面板,改用动态实例化卡槽

1. 移除静态绑定的卡槽节点,改用cardPrefab动态生成3个卡槽
2. 删除所有关闭面板按钮的事件绑定与回调函数
3. 简化面板显示隐藏逻辑,移除panelsHidden状态变量
4. 重构注释与变量命名,提升代码可读性
This commit is contained in:
panFD
2026-07-25 22:25:57 +08:00
parent ffafefcc72
commit 4ef2e13798

View File

@@ -15,7 +15,7 @@
* 6. **准备/战斗阶段切换** —— 控制卡牌面板的 展开/收起 动画。
*
* 关键设计:
* - 3 个 CardComp 通过 cacheCardComps() 映射为有序数组 cardComps[]
* - 3 个 CardComp 由 cardPrefab 动态实例化生成,通过 cacheCardComps() 映射为有序数组 cardComps[]
* 之后所有分发、清空操作均通过此数组进行。
* - buildDrawCards() 动态合并升级卡池和基础卡池后抽取 3 张,不足时循环补齐。
* - 英雄上限校验onUseHeroCard采用 guard/cancel 模式:
@@ -85,66 +85,60 @@ export class MissionCardComp extends CCComp {
// ======================== 编辑器绑定节点 ========================
/** 英雄卡牌面板根节点(战斗阶段收起,准备阶段展开) */
/** 英雄抽卡面板(战斗阶段收起,准备阶段展开) */
@property(Node)
showCards: Node = null!
@property(Node)
cardPanNode: Node = null!
@property(Node)
cards_node: Node = null!
/** 卡牌槽位 1 节点 */
@property(Node)
card1: Node = null!
/** 卡牌槽位 2 节点 */
@property(Node)
card2: Node = null!
/** 卡牌槽位 3 节点 */
@property(Node)
card3: Node = null!
/** 卡牌槽位预制体(动态实例化 3 个) */
@property(Prefab)
cardPrefab: Prefab = null!
/** 抽卡(刷新)按钮节点 */
@property(Node)
cards_chou: Node = null!
@property(Node)
closeCards: Node = null!
@property(Node)
nock_node: Node = null!
/** 英雄面板cards_node显示隐藏 */
/** 英雄面板显示按钮 */
@property(Node)
showHeros: Node = null!
@property(Node)
closeHeros: Node = null!
@property(Node)
herosPanNode: Node = null!
@property(Node)
herosBoxNode: Node = null!
@property(Prefab)
heroPrefab: Prefab = null!
/** 装备面板显示按钮 */
@property(Node)
showEquips: Node = null!
@property(Node)
closeEquips: Node = null!
@property(Node)
equipsPanNode: Node = null!
@property(Node)
equipsBoxNode: Node = null!
@property(Prefab)
equipPrefab: Prefab = null!
/** 技能面板显示按钮 */
@property(Node)
showSkills: Node = null!
@property(Node)
closeSkills: Node = null!
@property(Node)
skillPanNode: Node = null!
@property(Node)
skillBoxNode: Node = null!
@property(Prefab)
skillPrefab: Prefab = null!
/** 药品面板显示按钮 */
@property(Node)
showShop: Node = null!
@property(Node)
closeShop: Node = null!
@property(Node)
shopPanNode: Node = null!
@property(Node)
shopBoxNode: Node = null!
@@ -215,8 +209,6 @@ export class MissionCardComp extends CCComp {
private panelBaseYs: number[] = [];
/** 是否已初始化面板布局 */
private hasInitPanelLayout: boolean = false;
/** 面板是否处于隐藏状态(被 close 按钮关闭) */
private panelsHidden: boolean = false;
/** 是否已缓存卡牌面板基准缩放 */
private hasCachedCardsBaseScale: boolean = false;
/** 卡牌面板基准缩放(从场景读取) */
@@ -265,27 +257,15 @@ export class MissionCardComp extends CCComp {
if (this.showHeros && this.showHeros.isValid) {
this.showHeros.off(NodeEventType.TOUCH_END, this.onShowHerosClick, this);
}
if (this.closeHeros && this.closeHeros.isValid) {
this.closeHeros.off(NodeEventType.TOUCH_END, this.onCloseHerosClick, this);
}
if (this.showEquips && this.showEquips.isValid) {
this.showEquips.off(NodeEventType.TOUCH_END, this.onShowEquipsClick, this);
}
if (this.closeEquips && this.closeEquips.isValid) {
this.closeEquips.off(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
}
if (this.showSkills && this.showSkills.isValid) {
this.showSkills.off(NodeEventType.TOUCH_END, this.onShowSkillsClick, this);
}
if (this.closeSkills && this.closeSkills.isValid) {
this.closeSkills.off(NodeEventType.TOUCH_END, this.onCloseSkillsClick, this);
}
if (this.showShop && this.showShop.isValid) {
this.showShop.off(NodeEventType.TOUCH_END, this.onShowShopClick, this);
}
if (this.closeShop && this.closeShop.isValid) {
this.closeShop.off(NodeEventType.TOUCH_END, this.onCloseShopClick, this);
}
this.unbindEvents();
}
@@ -407,25 +387,17 @@ export class MissionCardComp extends CCComp {
this.cards_chou?.on(NodeEventType.TOUCH_END, this.onDrawTouchEnd, this);
this.cards_chou?.on(NodeEventType.TOUCH_CANCEL, this.onDrawTouchCancel, this);
/** 英雄卡池显示/隐藏切换按钮 */
/** 英雄面板显示按钮 */
this.showHeros?.on(NodeEventType.TOUCH_END, this.onShowHerosClick, this);
/** 关闭英雄卡池按钮 */
this.closeHeros?.on(NodeEventType.TOUCH_END, this.onCloseHerosClick, this);
/** 装备商店显示/隐藏切换按钮 */
/** 装备面板显示按钮 */
this.showEquips?.on(NodeEventType.TOUCH_END, this.onShowEquipsClick, this);
/** 关闭装备商店按钮 */
this.closeEquips?.on(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
/** 技能卡池显示按钮 */
/** 技能面板显示按钮 */
this.showSkills?.on(NodeEventType.TOUCH_END, this.onShowSkillsClick, this);
/** 关闭技能卡池按钮 */
this.closeSkills?.on(NodeEventType.TOUCH_END, this.onCloseSkillsClick, this);
/** 商店显示/隐藏切换按钮 */
/** 药品面板显示按钮 */
this.showShop?.on(NodeEventType.TOUCH_END, this.onShowShopClick, this);
/** 关闭商店按钮 */
this.closeShop?.on(NodeEventType.TOUCH_END, this.onCloseShopClick, this);
/** 技能卡刷新按钮 */
this.skill_refresh?.on(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
@@ -574,11 +546,6 @@ export class MissionCardComp extends CCComp {
this.slideToPanel(2);
}
/** 关闭技能面板按钮回调:隐藏所有面板 */
private onCloseSkillsClick() {
this.hideAllPanels();
}
// ======================== 商店面板 ========================
/**
@@ -589,11 +556,6 @@ export class MissionCardComp extends CCComp {
this.slideToPanel(3);
}
/** 关闭商店面板按钮回调:隐藏所有面板 */
private onCloseShopClick() {
this.hideAllPanels();
}
/**
* 填充商品列表:
* 从 ICardSet 按权重抽取 3 张商品卡,
@@ -708,15 +670,9 @@ export class MissionCardComp extends CCComp {
if (this.showHeros && this.showHeros.isValid) {
this.showHeros.off(NodeEventType.TOUCH_END, this.onShowHerosClick, this);
}
if (this.closeHeros && this.closeHeros.isValid) {
this.closeHeros.off(NodeEventType.TOUCH_END, this.onCloseHerosClick, this);
}
if (this.showEquips && this.showEquips.isValid) {
this.showEquips.off(NodeEventType.TOUCH_END, this.onShowEquipsClick, this);
}
if (this.closeEquips && this.closeEquips.isValid) {
this.closeEquips.off(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
}
if (this.skill_refresh && this.skill_refresh.isValid) {
this.skill_refresh.off(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
this.skill_refresh.off(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, this);
@@ -730,9 +686,6 @@ export class MissionCardComp extends CCComp {
if (this.showShop && this.showShop.isValid) {
this.showShop.off(NodeEventType.TOUCH_END, this.onShowShopClick, this);
}
if (this.closeShop && this.closeShop.isValid) {
this.closeShop.off(NodeEventType.TOUCH_END, this.onCloseShopClick, this);
}
if (this.equip_refresh && this.equip_refresh.isValid) {
this.equip_refresh.off(NodeEventType.TOUCH_START, this.onEquipDrawTouchStart, this);
this.equip_refresh.off(NodeEventType.TOUCH_END, this.onEquipDrawTouchEnd, this);
@@ -952,14 +905,6 @@ export class MissionCardComp extends CCComp {
const panels = this.getPanelNodes();
if (index < 0 || index >= panels.length) return;
// 如果面板被隐藏close先恢复显示
if (this.panelsHidden) {
this.panelsHidden = false;
for (const p of panels) {
if (p && p.isValid) p.active = true;
}
}
this.currentPanelIndex = index;
const duration = 0.25;
@@ -988,24 +933,11 @@ export class MissionCardComp extends CCComp {
if (!btn || !btn.isValid) continue;
const activeChild = btn.getChildByName("active");
if (activeChild) {
activeChild.active = (i === this.currentPanelIndex && !this.panelsHidden);
activeChild.active = (i === this.currentPanelIndex);
}
}
}
/**
* 隐藏所有面板(通过 close 按钮关闭)。
*/
private hideAllPanels() {
oops.audio.playEffect("music/button");
this.panelsHidden = true;
const panels = this.getPanelNodes();
for (const p of panels) {
if (p && p.isValid) p.active = false;
}
this.updatePanelButtonStates();
}
/**
* 更新面板按钮的可交互状态。
* 游戏刚开始时(未召唤英雄),只有英雄面板可打开;
@@ -1027,15 +959,6 @@ export class MissionCardComp extends CCComp {
this.slideToPanel(0);
}
/**
* 关闭英雄面板按钮回调:隐藏所有面板。
* 同步关闭已打开的英雄信息面板HInfo避免卡池收起后信息面板孤立悬浮。
*/
private onCloseHerosClick() {
this.hideAllPanels();
oops.gui.remove(UIID.HInfo);
}
// ======================== 装备商店面板 ========================
/**
@@ -1046,11 +969,6 @@ export class MissionCardComp extends CCComp {
this.slideToPanel(1);
}
/** 关闭装备面板按钮回调:隐藏所有面板 */
private onCloseEquipsClick() {
this.hideAllPanels();
}
/**
* 根据子项数量设置容器高度。
* 单项高度 100间隔 5上下各加 25 冗余(共 50
@@ -1199,12 +1117,25 @@ export class MissionCardComp extends CCComp {
this.populateShopItems();
}
/** 将个卡槽节点映射为 CardComp形成固定顺序控制数组 */
/** 将 cardPrefab 实例化为 3 个卡槽映射为 CardComp形成固定顺序控制数组 */
private cacheCardComps() {
const nodes = [this.card1, this.card2, this.card3];
this.cardComps = nodes
.map(node => node?.getComponent(CardComp))
.filter((comp): comp is CardComp => !!comp);
// 清理旧卡槽(如果存在)
for (const comp of this.cardComps) {
if (comp && comp.node && comp.node.isValid) {
comp.node.destroy();
}
}
this.cardComps = [];
// 从预制体实例化 3 个卡槽
if (this.cardPrefab && this.cards_node && this.cards_node.isValid) {
for (let i = 0; i < 3; i++) {
const node = instantiate(this.cardPrefab);
this.cards_node.addChild(node);
const comp = node.getComponent(CardComp) || node.addComponent(CardComp);
this.cardComps.push(comp);
}
}
const skillNodes = [this.skill_card1, this.skill_card2, this.skill_card3];
this.skillCardComps = skillNodes