feat(mission): 添加抽卡面板付费开启与按钮高亮逻辑
1. 重构任务面板抽卡相关逻辑,为四个抽卡/商店面板添加开启费用机制,每次使用后费用递增 2. 新增面板重复开启校验,避免重复扣费 3. 优化英雄抽卡按钮的高亮状态,与面板展开状态绑定 4. 调整预设文件中任务面板UI元素的位置与尺寸适配新逻辑 5. 新增费用显示UI更新,在按钮上展示当前开启成本
This commit is contained in:
@@ -99,7 +99,7 @@ export class MissionCardComp extends CCComp {
|
||||
nock_node: Node = null!
|
||||
|
||||
|
||||
/** 英雄面板显示按钮 */
|
||||
/** 英雄抽卡面板显示按钮 */
|
||||
@property(Node)
|
||||
showHeros: Node = null!
|
||||
@property(Node)
|
||||
@@ -191,6 +191,14 @@ export class MissionCardComp extends CCComp {
|
||||
private readonly panelHideScale: Vec3 = new Vec3(0, 0, 1);
|
||||
/** 是否已初始化面板布局 */
|
||||
private hasInitPanelLayout: boolean = false;
|
||||
/** 英雄抽卡面板是否处于展开状态(驱动 showHeros 按钮 active 高亮) */
|
||||
private isCardPanelShown: boolean = false;
|
||||
/** 抽卡面板开启初始金币费用 */
|
||||
private static readonly PANEL_OPEN_BASE_COST = 5;
|
||||
/** 抽卡面板每抽 1 次的费用递增 */
|
||||
private static readonly PANEL_OPEN_COST_STEP = 5;
|
||||
/** 各抽卡面板当前开启费用 [英雄抽卡, 装备, 技能, 药品] */
|
||||
private panelOpenCosts: number[] = [];
|
||||
/** 是否已缓存卡牌面板基准缩放 */
|
||||
private hasCachedCardsBaseScale: boolean = false;
|
||||
/** 卡牌面板基准缩放(从场景读取) */
|
||||
@@ -280,6 +288,7 @@ export class MissionCardComp extends CCComp {
|
||||
this.layoutCardSlots();
|
||||
this.clearAllCards();
|
||||
this.resetButtonScale(this.cards_chou);
|
||||
this.resetPanelOpenCosts();
|
||||
this.updateCoinAndCostUI();
|
||||
this.updateHeroNumUI(false, false);
|
||||
if (this.node && this.node.isValid) {
|
||||
@@ -507,6 +516,9 @@ export class MissionCardComp extends CCComp {
|
||||
*/
|
||||
private onShowSkillsClick() {
|
||||
oops.audio.playEffect("music/button");
|
||||
if (this.isOverlayPanelShown(2)) return;
|
||||
// 开启技能面板需支付金币,金币不足则提示并中止
|
||||
if (!this.tryPayPanelOpenCost(2)) return;
|
||||
this.slideToPanel(2);
|
||||
}
|
||||
|
||||
@@ -517,6 +529,9 @@ export class MissionCardComp extends CCComp {
|
||||
*/
|
||||
private onShowShopClick() {
|
||||
oops.audio.playEffect("music/button");
|
||||
if (this.isOverlayPanelShown(3)) return;
|
||||
// 开启药品面板需支付金币,金币不足则提示并中止
|
||||
if (!this.tryPayPanelOpenCost(3)) return;
|
||||
this.slideToPanel(3);
|
||||
}
|
||||
|
||||
@@ -866,6 +881,16 @@ export class MissionCardComp extends CCComp {
|
||||
return [this.showHeros, this.showEquips, this.showSkills, this.showShop];
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断覆盖面板(index≥1)当前是否处于展开状态,避免重复开启导致重复扣费。
|
||||
* @param index 面板下标(1=装备 2=技能 3=药品)
|
||||
*/
|
||||
private isOverlayPanelShown(index: number): boolean {
|
||||
if (this.currentPanelIndex !== index) return false;
|
||||
const node = this.getPanelNodes()[index];
|
||||
return !!node && node.isValid && node.active;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化面板布局:
|
||||
* 1. 英雄面板(index=0)为常驻基准面板,始终显示。
|
||||
@@ -961,7 +986,9 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 更新面板 tab 按钮的 active 子节点状态。
|
||||
* 当前激活面板对应的按钮 active 高亮,其余关闭。
|
||||
* 装备/技能/药品按钮按 currentPanelIndex 高亮;
|
||||
* 英雄抽卡面板(cardPanNode)不在覆盖面板数组内,
|
||||
* showHeros 按钮按 isCardPanelShown 高亮:面板展开时显示 active,关闭时隐藏。
|
||||
*/
|
||||
private updatePanelButtonStates() {
|
||||
const buttons = this.getPanelShowButtons();
|
||||
@@ -970,7 +997,8 @@ export class MissionCardComp extends CCComp {
|
||||
if (!btn || !btn.isValid) continue;
|
||||
const activeChild = btn.getChildByName("active");
|
||||
if (activeChild) {
|
||||
activeChild.active = (i === this.currentPanelIndex);
|
||||
const shouldActive = i === 0 ? this.isCardPanelShown : (i === this.currentPanelIndex);
|
||||
activeChild.active = shouldActive;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -989,11 +1017,20 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
/**
|
||||
* 英雄面板按钮回调:收起覆盖面板,回到英雄面板(index=0)。
|
||||
* 英雄面板按钮回调:
|
||||
* 英雄面板(herosPanNode)为常驻基准面板,固定不动;
|
||||
* 点击按钮收起装备/技能/药品覆盖面板,并显示英雄抽卡面板(cardPanNode)。
|
||||
*/
|
||||
private onShowHerosClick() {
|
||||
oops.audio.playEffect("music/button");
|
||||
// 已展开则不重复开启(不重复扣费)
|
||||
if (this.isCardPanelShown) return;
|
||||
// 开启英雄抽卡面板需支付金币,金币不足则提示并中止
|
||||
if (!this.tryPayPanelOpenCost(0)) return;
|
||||
// 收起装备/技能/药品覆盖面板
|
||||
this.slideToPanel(0);
|
||||
// 显示英雄抽卡面板(缩放 0→1,并点亮按钮 active 高亮)
|
||||
this.showCardsPanel();
|
||||
}
|
||||
|
||||
// ======================== 英雄信息盒(herosBoxNode) ========================
|
||||
@@ -1061,12 +1098,59 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付抽卡面板开启费用:
|
||||
* 金币足够则扣除当前费用,并将该面板费用递增 PANEL_OPEN_COST_STEP;
|
||||
* 不足则弹出"金币不足"小提示并返回 false。
|
||||
* @param panelIndex 面板下标(0=英雄抽卡 1=装备 2=技能 3=药品)
|
||||
* @returns 是否支付成功
|
||||
*/
|
||||
private tryPayPanelOpenCost(panelIndex: number): boolean {
|
||||
const cost = this.panelOpenCosts[panelIndex] ?? MissionCardComp.PANEL_OPEN_BASE_COST;
|
||||
if (!MissionEconomy.spendCoin(cost)) {
|
||||
oops.message.dispatchEvent(GameEvent.ShowSmallTip, "buy_coin");
|
||||
return false;
|
||||
}
|
||||
this.panelOpenCosts[panelIndex] = cost + MissionCardComp.PANEL_OPEN_COST_STEP;
|
||||
this.updatePanelOpenCostUI();
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 重置 4 个抽卡面板开启费用为初始值(任务开始时调用) */
|
||||
private resetPanelOpenCosts() {
|
||||
this.panelOpenCosts = [
|
||||
MissionCardComp.PANEL_OPEN_BASE_COST,
|
||||
MissionCardComp.PANEL_OPEN_BASE_COST,
|
||||
MissionCardComp.PANEL_OPEN_BASE_COST,
|
||||
MissionCardComp.PANEL_OPEN_BASE_COST
|
||||
];
|
||||
this.updatePanelOpenCostUI();
|
||||
}
|
||||
|
||||
/** 刷新 4 个显示按钮上的开启费用显示(按钮下无 cost/num 标签子节点时自动跳过) */
|
||||
private updatePanelOpenCostUI() {
|
||||
const buttons = this.getPanelShowButtons();
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
const btn = buttons[i];
|
||||
if (!btn || !btn.isValid) continue;
|
||||
const costNode = btn.getChildByName("cost") ?? btn.getChildByName("num");
|
||||
const label = costNode ? costNode.getComponent(Label) : null;
|
||||
if (label) {
|
||||
label.string = `${this.panelOpenCosts[i] ?? MissionCardComp.PANEL_OPEN_BASE_COST}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示卡牌面板:缩放从 0 动画放大到 1
|
||||
*/
|
||||
private onShowCardsClick() {
|
||||
oops.audio.playEffect("music/button");
|
||||
this.showOverlayPanel(this.cardPanNode);
|
||||
// 已展开则不重复开启(不重复扣费)
|
||||
if (this.isCardPanelShown) return;
|
||||
// 空槽位点开英雄抽卡面板同样需支付金币
|
||||
if (!this.tryPayPanelOpenCost(0)) return;
|
||||
this.showCardsPanel();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1077,9 +1161,21 @@ export class MissionCardComp extends CCComp {
|
||||
this.hideCardsPanel();
|
||||
}
|
||||
|
||||
/** 隐藏卡牌面板:缩放缩小到 0(不含按钮音效,供系统逻辑复用) */
|
||||
/**
|
||||
* 显示卡牌面板:缩放 0→1,并点亮 showHeros 按钮的 active 高亮。
|
||||
* 统一开合入口,供按钮点击与系统逻辑复用。
|
||||
*/
|
||||
private showCardsPanel() {
|
||||
this.isCardPanelShown = true;
|
||||
this.showOverlayPanel(this.cardPanNode);
|
||||
this.updatePanelButtonStates();
|
||||
}
|
||||
|
||||
/** 隐藏卡牌面板:缩放缩小到 0,同时隐藏 showHeros 按钮的 active 高亮 */
|
||||
private hideCardsPanel() {
|
||||
this.isCardPanelShown = false;
|
||||
this.hideOverlayPanelNode(this.cardPanNode);
|
||||
this.updatePanelButtonStates();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1105,6 +1201,9 @@ export class MissionCardComp extends CCComp {
|
||||
*/
|
||||
private onShowEquipsClick() {
|
||||
oops.audio.playEffect("music/button");
|
||||
if (this.isOverlayPanelShown(1)) return;
|
||||
// 开启装备面板需支付金币,金币不足则提示并中止
|
||||
if (!this.tryPayPanelOpenCost(1)) return;
|
||||
this.slideToPanel(1);
|
||||
}
|
||||
|
||||
@@ -1503,9 +1602,9 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
// 刷新所有刷新按钮的费用显示(含刷新石/金币切换与置灰状态)
|
||||
this.updateDrawCostUI();
|
||||
// 显示卡牌面板(默认进入准备阶段时展开,缩放放大到 1)
|
||||
// 显示卡牌面板(默认进入准备阶段时展开,缩放放大到 1,点亮按钮 active 高亮)
|
||||
if (this.cardPanNode && this.cardPanNode.isValid) {
|
||||
this.showOverlayPanel(this.cardPanNode);
|
||||
this.showCardsPanel();
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "enterPreparePhase cardPanNode", {
|
||||
active: this.cardPanNode.active,
|
||||
position: this.cardPanNode.position,
|
||||
|
||||
Reference in New Issue
Block a user