refactor(map): 重构任务卡牌面板,改用动态实例化卡槽
1. 移除静态绑定的卡槽节点,改用cardPrefab动态生成3个卡槽 2. 删除所有关闭面板按钮的事件绑定与回调函数 3. 简化面板显示隐藏逻辑,移除panelsHidden状态变量 4. 重构注释与变量命名,提升代码可读性
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
* 6. **准备/战斗阶段切换** —— 控制卡牌面板的 展开/收起 动画。
|
* 6. **准备/战斗阶段切换** —— 控制卡牌面板的 展开/收起 动画。
|
||||||
*
|
*
|
||||||
* 关键设计:
|
* 关键设计:
|
||||||
* - 3 个 CardComp 通过 cacheCardComps() 映射为有序数组 cardComps[],
|
* - 3 个 CardComp 由 cardPrefab 动态实例化生成,通过 cacheCardComps() 映射为有序数组 cardComps[],
|
||||||
* 之后所有分发、清空操作均通过此数组进行。
|
* 之后所有分发、清空操作均通过此数组进行。
|
||||||
* - buildDrawCards() 动态合并升级卡池和基础卡池后抽取 3 张,不足时循环补齐。
|
* - buildDrawCards() 动态合并升级卡池和基础卡池后抽取 3 张,不足时循环补齐。
|
||||||
* - 英雄上限校验(onUseHeroCard)采用 guard/cancel 模式:
|
* - 英雄上限校验(onUseHeroCard)采用 guard/cancel 模式:
|
||||||
@@ -85,66 +85,60 @@ export class MissionCardComp extends CCComp {
|
|||||||
|
|
||||||
// ======================== 编辑器绑定节点 ========================
|
// ======================== 编辑器绑定节点 ========================
|
||||||
|
|
||||||
/** 英雄卡牌面板根节点(战斗阶段收起,准备阶段展开) */
|
/** 英雄抽卡面板(战斗阶段收起,准备阶段展开) */
|
||||||
@property(Node)
|
@property(Node)
|
||||||
showCards: Node = null!
|
showCards: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
|
cardPanNode: Node = null!
|
||||||
|
@property(Node)
|
||||||
cards_node: Node = null!
|
cards_node: Node = null!
|
||||||
/** 卡牌槽位 1 节点 */
|
/** 卡牌槽位预制体(动态实例化 3 个) */
|
||||||
@property(Node)
|
@property(Prefab)
|
||||||
card1: Node = null!
|
cardPrefab: Prefab = null!
|
||||||
/** 卡牌槽位 2 节点 */
|
|
||||||
@property(Node)
|
|
||||||
card2: Node = null!
|
|
||||||
/** 卡牌槽位 3 节点 */
|
|
||||||
@property(Node)
|
|
||||||
card3: Node = null!
|
|
||||||
/** 抽卡(刷新)按钮节点 */
|
/** 抽卡(刷新)按钮节点 */
|
||||||
@property(Node)
|
@property(Node)
|
||||||
cards_chou: Node = null!
|
cards_chou: Node = null!
|
||||||
|
@property(Node)
|
||||||
|
closeCards: Node = null!
|
||||||
|
|
||||||
@property(Node)
|
@property(Node)
|
||||||
nock_node: Node = null!
|
nock_node: Node = null!
|
||||||
|
|
||||||
|
|
||||||
/** 英雄面板cards_node显示隐藏 */
|
/** 英雄面板显示按钮 */
|
||||||
@property(Node)
|
@property(Node)
|
||||||
showHeros: Node = null!
|
showHeros: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
closeHeros: Node = null!
|
|
||||||
@property(Node)
|
|
||||||
herosPanNode: Node = null!
|
herosPanNode: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
herosBoxNode: Node = null!
|
herosBoxNode: Node = null!
|
||||||
@property(Prefab)
|
@property(Prefab)
|
||||||
heroPrefab: Prefab = null!
|
heroPrefab: Prefab = null!
|
||||||
|
|
||||||
|
/** 装备面板显示按钮 */
|
||||||
@property(Node)
|
@property(Node)
|
||||||
showEquips: Node = null!
|
showEquips: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
closeEquips: Node = null!
|
|
||||||
@property(Node)
|
|
||||||
equipsPanNode: Node = null!
|
equipsPanNode: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
equipsBoxNode: Node = null!
|
equipsBoxNode: Node = null!
|
||||||
@property(Prefab)
|
@property(Prefab)
|
||||||
equipPrefab: Prefab = null!
|
equipPrefab: Prefab = null!
|
||||||
|
|
||||||
|
/** 技能面板显示按钮 */
|
||||||
@property(Node)
|
@property(Node)
|
||||||
showSkills: Node = null!
|
showSkills: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
closeSkills: Node = null!
|
|
||||||
@property(Node)
|
|
||||||
skillPanNode: Node = null!
|
skillPanNode: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
skillBoxNode: Node = null!
|
skillBoxNode: Node = null!
|
||||||
@property(Prefab)
|
@property(Prefab)
|
||||||
skillPrefab: Prefab = null!
|
skillPrefab: Prefab = null!
|
||||||
|
|
||||||
|
/** 药品面板显示按钮 */
|
||||||
@property(Node)
|
@property(Node)
|
||||||
showShop: Node = null!
|
showShop: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
closeShop: Node = null!
|
|
||||||
@property(Node)
|
|
||||||
shopPanNode: Node = null!
|
shopPanNode: Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
shopBoxNode: Node = null!
|
shopBoxNode: Node = null!
|
||||||
@@ -215,8 +209,6 @@ export class MissionCardComp extends CCComp {
|
|||||||
private panelBaseYs: number[] = [];
|
private panelBaseYs: number[] = [];
|
||||||
/** 是否已初始化面板布局 */
|
/** 是否已初始化面板布局 */
|
||||||
private hasInitPanelLayout: boolean = false;
|
private hasInitPanelLayout: boolean = false;
|
||||||
/** 面板是否处于隐藏状态(被 close 按钮关闭) */
|
|
||||||
private panelsHidden: boolean = false;
|
|
||||||
/** 是否已缓存卡牌面板基准缩放 */
|
/** 是否已缓存卡牌面板基准缩放 */
|
||||||
private hasCachedCardsBaseScale: boolean = false;
|
private hasCachedCardsBaseScale: boolean = false;
|
||||||
/** 卡牌面板基准缩放(从场景读取) */
|
/** 卡牌面板基准缩放(从场景读取) */
|
||||||
@@ -265,27 +257,15 @@ export class MissionCardComp extends CCComp {
|
|||||||
if (this.showHeros && this.showHeros.isValid) {
|
if (this.showHeros && this.showHeros.isValid) {
|
||||||
this.showHeros.off(NodeEventType.TOUCH_END, this.onShowHerosClick, this);
|
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) {
|
if (this.showEquips && this.showEquips.isValid) {
|
||||||
this.showEquips.off(NodeEventType.TOUCH_END, this.onShowEquipsClick, this);
|
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) {
|
if (this.showSkills && this.showSkills.isValid) {
|
||||||
this.showSkills.off(NodeEventType.TOUCH_END, this.onShowSkillsClick, this);
|
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) {
|
if (this.showShop && this.showShop.isValid) {
|
||||||
this.showShop.off(NodeEventType.TOUCH_END, this.onShowShopClick, this);
|
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();
|
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_END, this.onDrawTouchEnd, this);
|
||||||
this.cards_chou?.on(NodeEventType.TOUCH_CANCEL, this.onDrawTouchCancel, this);
|
this.cards_chou?.on(NodeEventType.TOUCH_CANCEL, this.onDrawTouchCancel, this);
|
||||||
|
|
||||||
/** 英雄卡池显示/隐藏切换按钮 */
|
/** 英雄面板显示按钮 */
|
||||||
this.showHeros?.on(NodeEventType.TOUCH_END, this.onShowHerosClick, 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.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.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.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);
|
this.skill_refresh?.on(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
||||||
@@ -574,11 +546,6 @@ export class MissionCardComp extends CCComp {
|
|||||||
this.slideToPanel(2);
|
this.slideToPanel(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 关闭技能面板按钮回调:隐藏所有面板 */
|
|
||||||
private onCloseSkillsClick() {
|
|
||||||
this.hideAllPanels();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======================== 商店面板 ========================
|
// ======================== 商店面板 ========================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -589,11 +556,6 @@ export class MissionCardComp extends CCComp {
|
|||||||
this.slideToPanel(3);
|
this.slideToPanel(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 关闭商店面板按钮回调:隐藏所有面板 */
|
|
||||||
private onCloseShopClick() {
|
|
||||||
this.hideAllPanels();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 填充商品列表:
|
* 填充商品列表:
|
||||||
* 从 ICardSet 按权重抽取 3 张商品卡,
|
* 从 ICardSet 按权重抽取 3 张商品卡,
|
||||||
@@ -708,15 +670,9 @@ export class MissionCardComp extends CCComp {
|
|||||||
if (this.showHeros && this.showHeros.isValid) {
|
if (this.showHeros && this.showHeros.isValid) {
|
||||||
this.showHeros.off(NodeEventType.TOUCH_END, this.onShowHerosClick, this);
|
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) {
|
if (this.showEquips && this.showEquips.isValid) {
|
||||||
this.showEquips.off(NodeEventType.TOUCH_END, this.onShowEquipsClick, this);
|
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) {
|
if (this.skill_refresh && this.skill_refresh.isValid) {
|
||||||
this.skill_refresh.off(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
this.skill_refresh.off(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
||||||
this.skill_refresh.off(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, 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) {
|
if (this.showShop && this.showShop.isValid) {
|
||||||
this.showShop.off(NodeEventType.TOUCH_END, this.onShowShopClick, this);
|
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) {
|
if (this.equip_refresh && this.equip_refresh.isValid) {
|
||||||
this.equip_refresh.off(NodeEventType.TOUCH_START, this.onEquipDrawTouchStart, this);
|
this.equip_refresh.off(NodeEventType.TOUCH_START, this.onEquipDrawTouchStart, this);
|
||||||
this.equip_refresh.off(NodeEventType.TOUCH_END, this.onEquipDrawTouchEnd, this);
|
this.equip_refresh.off(NodeEventType.TOUCH_END, this.onEquipDrawTouchEnd, this);
|
||||||
@@ -952,14 +905,6 @@ export class MissionCardComp extends CCComp {
|
|||||||
const panels = this.getPanelNodes();
|
const panels = this.getPanelNodes();
|
||||||
if (index < 0 || index >= panels.length) return;
|
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;
|
this.currentPanelIndex = index;
|
||||||
const duration = 0.25;
|
const duration = 0.25;
|
||||||
|
|
||||||
@@ -988,24 +933,11 @@ export class MissionCardComp extends CCComp {
|
|||||||
if (!btn || !btn.isValid) continue;
|
if (!btn || !btn.isValid) continue;
|
||||||
const activeChild = btn.getChildByName("active");
|
const activeChild = btn.getChildByName("active");
|
||||||
if (activeChild) {
|
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);
|
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);
|
this.slideToPanel(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 关闭装备面板按钮回调:隐藏所有面板 */
|
|
||||||
private onCloseEquipsClick() {
|
|
||||||
this.hideAllPanels();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据子项数量设置容器高度。
|
* 根据子项数量设置容器高度。
|
||||||
* 单项高度 100,间隔 5,上下各加 25 冗余(共 50)。
|
* 单项高度 100,间隔 5,上下各加 25 冗余(共 50)。
|
||||||
@@ -1199,12 +1117,25 @@ export class MissionCardComp extends CCComp {
|
|||||||
this.populateShopItems();
|
this.populateShopItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 将三个卡槽节点映射为 CardComp,形成固定顺序控制数组 */
|
/** 将 cardPrefab 实例化为 3 个卡槽并映射为 CardComp,形成固定顺序控制数组 */
|
||||||
private cacheCardComps() {
|
private cacheCardComps() {
|
||||||
const nodes = [this.card1, this.card2, this.card3];
|
// 清理旧卡槽(如果存在)
|
||||||
this.cardComps = nodes
|
for (const comp of this.cardComps) {
|
||||||
.map(node => node?.getComponent(CardComp))
|
if (comp && comp.node && comp.node.isValid) {
|
||||||
.filter((comp): comp is CardComp => !!comp);
|
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];
|
const skillNodes = [this.skill_card1, this.skill_card2, this.skill_card3];
|
||||||
this.skillCardComps = skillNodes
|
this.skillCardComps = skillNodes
|
||||||
|
|||||||
Reference in New Issue
Block a user