refactor: 将刷新石替换为银币作为卡牌刷新消耗
1. 重构全局配置,移除刷新石相关定义,新增银币刷新消耗常量 2. 新增局外持久货币银币的数据结构与管理逻辑 3. 重构卡牌刷新经济系统,统一使用银币进行刷新消耗 4. 更新UI显示与事件通知,适配银币系统变更 5. 调整清屏奖励逻辑,将刷新石奖励改为金币奖励
This commit is contained in:
@@ -81,8 +81,6 @@ export class MissionCardComp extends CCComp {
|
||||
private readonly buttonPressScale: number = 0.94;
|
||||
/** 按钮弹起缩放(峰值) */
|
||||
private readonly buttonClickScale: number = 1.06;
|
||||
/** 抽卡(刷新)费用 */
|
||||
refreshCost: number = FightSet.REFRESH_COST;
|
||||
/** 卡牌面板展开/收起动画时长(秒) */
|
||||
cardsPanelMoveDuration: number = 0.2;
|
||||
|
||||
@@ -170,7 +168,7 @@ export class MissionCardComp extends CCComp {
|
||||
/** 英雄数量显示节点(含 icon + num 子节点) */
|
||||
@property(Node)
|
||||
hero_num_node: Node = null!
|
||||
/** 刷新石数量显示节点(含 icon + num 子节点) */
|
||||
/** 银币数量显示节点(含 icon + num 子节点) */
|
||||
@property(Node)
|
||||
refresh_stone_num_node: Node = null!
|
||||
|
||||
@@ -330,6 +328,7 @@ export class MissionCardComp extends CCComp {
|
||||
this.resetButtonScale(this.cards_refresh);
|
||||
this.resetPanelOpenCosts();
|
||||
this.updateCoinAndCostUI();
|
||||
this.updateSilverNumUI();
|
||||
this.updateHeroNumUI(false, false);
|
||||
if (this.node && this.node.isValid) {
|
||||
this.node.active = true;
|
||||
@@ -416,7 +415,7 @@ export class MissionCardComp extends CCComp {
|
||||
this.on("PhasePrepareStart", this.onPhasePrepareStart, this);
|
||||
|
||||
oops.message.on(GameEvent.CoinAdd, this.onCoinAdd, this);
|
||||
oops.message.on(GameEvent.RefreshStone, this.onRefreshStone, this);
|
||||
oops.message.on(GameEvent.SILVER_UPDATE, this.onSilverUpdate, this);
|
||||
oops.message.on(GameEvent.MasterCalled, this.onMasterCalled, this);
|
||||
oops.message.on(GameEvent.HeroDead, this.onHeroDead, this);
|
||||
oops.message.on(GameEvent.HeroSell, this.onHeroSell, this);
|
||||
@@ -477,13 +476,14 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
/** 刷新石数量变更:刷新刷新按钮状态/费用显示,并播放数量变化动画 */
|
||||
private onRefreshStone(event: string, args: any) {
|
||||
/** 银币数量变更:刷新银币数值显示 + 刷新按钮状态/费用显示,并播放数量变化动画 */
|
||||
private onSilverUpdate(event: string, args: any) {
|
||||
const payload = args ?? event;
|
||||
const v = typeof payload === 'number' ? payload : (payload?.delta ?? payload?.value ?? 0);
|
||||
this.updateSilverNumUI();
|
||||
this.updateDrawCostUI();
|
||||
if (v !== 0) {
|
||||
this.playRefreshStoneChangeAnim(v > 0);
|
||||
this.playSilverChangeAnim(v > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,9 +506,10 @@ export class MissionCardComp extends CCComp {
|
||||
* 挂在 showHeros / showEquips / showSkills / showShop 按钮节点(按钮下需预置 smalltip 子节点)
|
||||
* @param text 可选:覆盖气泡文字(默认读 prefab 中配置的文本)
|
||||
*/
|
||||
public showSmallTip(type: "refresh_coin" | "buy_coin" | "hero_full" | "panel_hero_full" | "panel_equip_full" | "panel_skill_full" | "panel_shop_full", text?: string) {
|
||||
public showSmallTip(type: "refresh_silver" | "refresh_coin" | "buy_coin" | "hero_full" | "panel_hero_full" | "panel_equip_full" | "panel_skill_full" | "panel_shop_full", text?: string) {
|
||||
let targetNode: Node | null = null;
|
||||
switch (type) {
|
||||
case "refresh_silver":
|
||||
case "refresh_coin":
|
||||
targetNode = this.cards_refresh;
|
||||
break;
|
||||
@@ -673,7 +674,7 @@ export class MissionCardComp extends CCComp {
|
||||
/** 解除按钮监听,避免节点销毁后回调泄漏 */
|
||||
private unbindEvents() {
|
||||
oops.message.off(GameEvent.CoinAdd, this.onCoinAdd, this);
|
||||
oops.message.off(GameEvent.RefreshStone, this.onRefreshStone, this);
|
||||
oops.message.off(GameEvent.SILVER_UPDATE, this.onSilverUpdate, this);
|
||||
oops.message.off(GameEvent.MasterCalled, this.onMasterCalled, this);
|
||||
oops.message.off(GameEvent.HeroDead, this.onHeroDead, this);
|
||||
oops.message.off(GameEvent.HeroSell, this.onHeroSell, this);
|
||||
@@ -1447,10 +1448,9 @@ export class MissionCardComp extends CCComp {
|
||||
this.playButtonResetAnim(this.skill_refresh);
|
||||
}
|
||||
|
||||
/** 装备刷新:扣费后重新抽取 3 张装备展示 */
|
||||
/** 装备刷新:扣银币后重新抽取 3 张装备展示 */
|
||||
private onClickEquipRefresh() {
|
||||
const cost = MissionEconomy.getRefreshCost(this.refreshCost);
|
||||
const success = MissionEconomy.executeRefresh(this.refreshCost);
|
||||
const success = MissionEconomy.executeRefresh();
|
||||
if (!success) {
|
||||
this.showSmallTip("refresh_coin");
|
||||
return;
|
||||
@@ -1458,10 +1458,9 @@ export class MissionCardComp extends CCComp {
|
||||
this.populateEquipments();
|
||||
}
|
||||
|
||||
/** 药品刷新:扣费后重新抽取 3 张商品展示 */
|
||||
/** 药品刷新:扣银币后重新抽取 3 张商品展示 */
|
||||
private onClickShopRefresh() {
|
||||
const cost = MissionEconomy.getRefreshCost(this.refreshCost);
|
||||
const success = MissionEconomy.executeRefresh(this.refreshCost);
|
||||
const success = MissionEconomy.executeRefresh();
|
||||
if (!success) {
|
||||
this.showSmallTip("refresh_coin");
|
||||
return;
|
||||
@@ -1469,9 +1468,9 @@ export class MissionCardComp extends CCComp {
|
||||
this.populateShopItems();
|
||||
}
|
||||
|
||||
/** 技能刷新:扣费后重新抽取 3 张技能卡展示 */
|
||||
/** 技能刷新:扣银币后重新抽取 3 张技能卡展示 */
|
||||
private onClickSkillRefresh() {
|
||||
const success = MissionEconomy.executeRefresh(this.refreshCost);
|
||||
const success = MissionEconomy.executeRefresh();
|
||||
if (!success) {
|
||||
this.showSmallTip("refresh_coin");
|
||||
return;
|
||||
@@ -1568,18 +1567,18 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 刷新卡池按钮核心逻辑:
|
||||
* 1. 检查金币/刷新石是否足够 → 不够则 toast 提示。
|
||||
* 2. 扣除费用、播放金币动画。
|
||||
* 1. 检查银币是否足够 → 不够则 toast 提示。
|
||||
* 2. 扣除银币费用。
|
||||
* 3. 重新布局槽位 → 从卡池构建 3 张卡 → 分发到槽位(三选一展示)。
|
||||
*/
|
||||
private onClickDraw() {
|
||||
const cost = MissionEconomy.getRefreshCost(this.refreshCost);
|
||||
const success = MissionEconomy.executeRefresh(this.refreshCost);
|
||||
const cost = MissionEconomy.getSilverRefreshCost();
|
||||
const success = MissionEconomy.executeRefresh();
|
||||
if (!success) {
|
||||
this.showSmallTip("refresh_coin");
|
||||
this.showSmallTip("refresh_silver", "银币不足");
|
||||
this.updateCoinAndCostUI();
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "draw coin not enough", {
|
||||
currentCoin: MissionEconomy.getCoin(),
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "draw silver not enough", {
|
||||
currentSilver: MissionEconomy.getSilver(),
|
||||
cost
|
||||
});
|
||||
return;
|
||||
@@ -1587,7 +1586,7 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "click refresh", {
|
||||
cost,
|
||||
leftCoin: MissionEconomy.getCoin()
|
||||
leftSilver: MissionEconomy.getSilver()
|
||||
});
|
||||
this.layoutCardSlots();
|
||||
const cards = this.buildDrawCards();
|
||||
@@ -1626,8 +1625,10 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
// 开局三选一期满后永久隐藏 showHeros(战前限定,不随阶段恢复)
|
||||
this.updateShowHerosVisibility();
|
||||
// 刷新所有刷新按钮的费用显示(含刷新石/金币切换与置灰状态)
|
||||
// 刷新所有刷新按钮的费用显示(含银币置灰状态)
|
||||
this.updateDrawCostUI();
|
||||
// 同步银币数量显示(阶段切换时确保数值最新)
|
||||
this.updateSilverNumUI();
|
||||
// 显示卡牌面板(默认进入准备阶段时展开,缩放放大到 1,点亮按钮 active 高亮)
|
||||
if (this.cardPanNode && this.cardPanNode.isValid) {
|
||||
this.showCardsPanel();
|
||||
@@ -1851,17 +1852,17 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
private canDrawCards() {
|
||||
// 有刷新石时可直接刷新,否则校验金币是否足够
|
||||
return MissionEconomy.canRefresh(this.refreshCost);
|
||||
// 银币足够时才可刷新
|
||||
return MissionEconomy.canRefresh();
|
||||
}
|
||||
|
||||
private updateDrawCostUI() {
|
||||
const stones = MissionEconomy.getRefreshStone();
|
||||
const stoneCost = MissionEconomy.getRefreshStoneCost();
|
||||
this.updateOneRefreshBtnUI(this.cards_refresh, stones, stoneCost);
|
||||
this.updateOneRefreshBtnUI(this.equip_refresh, stones, stoneCost);
|
||||
this.updateOneRefreshBtnUI(this.shop_refresh, stones, stoneCost);
|
||||
this.updateOneRefreshBtnUI(this.skill_refresh, stones, stoneCost);
|
||||
const silver = MissionEconomy.getSilver();
|
||||
const silverCost = MissionEconomy.getSilverRefreshCost();
|
||||
this.updateOneRefreshBtnUI(this.cards_refresh, silver, silverCost);
|
||||
this.updateOneRefreshBtnUI(this.equip_refresh, silver, silverCost);
|
||||
this.updateOneRefreshBtnUI(this.shop_refresh, silver, silverCost);
|
||||
this.updateOneRefreshBtnUI(this.skill_refresh, silver, silverCost);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1871,50 +1872,42 @@ export class MissionCardComp extends CCComp {
|
||||
* - 背景 :按钮底图
|
||||
* - nobg :置灰遮罩,不可刷新时激活
|
||||
* - Node/ :费用容器,下含 Label + coin + stone
|
||||
* - coin/ :金币费用(含 num 子节点 Label),刷新石=0 时显示
|
||||
* - stone/ :刷新石费用(含 num 子节点 Label),刷新石>0 时显示
|
||||
* - coin/ :金币费用(含 num 子节点 Label),银币机制下隐藏
|
||||
* - stone/ :银币数量(含 num 子节点 Label),显示当前持有银币数
|
||||
*
|
||||
* @param btnNode 刷新按钮节点
|
||||
* @param stones 当前刷新石数量(外部统一读取,避免 4 次重复访问)
|
||||
* @param stoneCost 单次刷新消耗的刷新石数量
|
||||
* @param silver 当前银币数量(外部统一读取,避免 4 次重复访问)
|
||||
* @param silverCost 单次刷新消耗的银币数量(仅用于判断是否置灰)
|
||||
*/
|
||||
private updateOneRefreshBtnUI(btnNode: Node | null, stones: number, stoneCost: number) {
|
||||
private updateOneRefreshBtnUI(btnNode: Node | null, silver: number, silverCost: number) {
|
||||
if (!btnNode || !btnNode.isValid) return;
|
||||
|
||||
// 刷新石足够一次消耗时走刷新石通道,否则走金币通道
|
||||
const useStone = stones >= stoneCost;
|
||||
// 银币足够一次消耗时走银币通道
|
||||
const useSilver = silver >= silverCost;
|
||||
|
||||
// 置灰遮罩:有刷新石必定可刷新,否则按金币判断
|
||||
// 置灰遮罩:银币不足时置灰
|
||||
const nobg = btnNode.getChildByName("nobg");
|
||||
if (nobg) {
|
||||
nobg.active = useStone ? false : !this.canDrawCards();
|
||||
nobg.active = !useSilver;
|
||||
}
|
||||
|
||||
// 费用容器:按钮下的 Node 子节点(统一结构:背景 + Node[Label/coin/stone])
|
||||
const container = btnNode.getChildByName("Node");
|
||||
if (!container) return;
|
||||
|
||||
// 金币费用节点
|
||||
// 金币费用节点:银币机制下隐藏,不再显示金币费用
|
||||
const coinNode = container.getChildByName("coin");
|
||||
if (coinNode) {
|
||||
coinNode.active = !useStone;
|
||||
if (!useStone) {
|
||||
const numLabel = coinNode.getChildByName("num")?.getComponent(Label);
|
||||
if (numLabel) {
|
||||
numLabel.string = `${MissionEconomy.getRefreshCost(this.refreshCost)}`;
|
||||
}
|
||||
}
|
||||
coinNode.active = false;
|
||||
}
|
||||
|
||||
// 刷新石费用节点(显示单次刷新消耗数量)
|
||||
// 银币费用节点(复用 stone 子节点结构,显示当前持有银币数量)
|
||||
const stoneNode = container.getChildByName("stone");
|
||||
if (stoneNode) {
|
||||
stoneNode.active = useStone;
|
||||
if (useStone) {
|
||||
const numLabel = stoneNode.getChildByName("num")?.getComponent(Label);
|
||||
if (numLabel) {
|
||||
numLabel.string = `${stoneCost}`;
|
||||
}
|
||||
stoneNode.active = true;
|
||||
const numLabel = stoneNode.getChildByName("num")?.getComponent(Label);
|
||||
if (numLabel) {
|
||||
numLabel.string = `${silver}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1930,6 +1923,17 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
/** 刷新银币数量显示(refresh_stone_num_node 下的 num Label),未绑定或节点失效时静默跳过 */
|
||||
private updateSilverNumUI() {
|
||||
if (!this.refresh_stone_num_node || !this.refresh_stone_num_node.isValid) return;
|
||||
const numNode = this.refresh_stone_num_node.getChildByName("num");
|
||||
if (!numNode || !numNode.isValid) return;
|
||||
const label = numNode.getComponent(Label);
|
||||
if (label) {
|
||||
label.string = `${MissionEconomy.getSilver()}`;
|
||||
}
|
||||
}
|
||||
|
||||
private playCoinChangeAnim(isIncrease: boolean) {
|
||||
if (!this.coins_node || !this.coins_node.isValid) return;
|
||||
const icon = this.coins_node.getChildByName("icon");
|
||||
@@ -1941,8 +1945,8 @@ export class MissionCardComp extends CCComp {
|
||||
this.playHeroNumNodePop(num, peak);
|
||||
}
|
||||
|
||||
/** 刷新石计数变化动画(与金币一致的 icon+num 弹跳) */
|
||||
private playRefreshStoneChangeAnim(isIncrease: boolean) {
|
||||
/** 银币计数变化动画(与金币一致的 icon+num 弹跳) */
|
||||
private playSilverChangeAnim(isIncrease: boolean) {
|
||||
if (!this.refresh_stone_num_node || !this.refresh_stone_num_node.isValid) return;
|
||||
const peak = isIncrease ? 1.2 : 1.2;
|
||||
const icon = this.refresh_stone_num_node.getChildByName("icon");
|
||||
|
||||
Reference in New Issue
Block a user