feat(shop): 新增商品/药品卡池与商店系统
1. 新增ICardSet.ts定义商品卡池配置,包含基础/高级恢复类、属性强化类道具 2. 为MissionCardComp添加商品商店逻辑,支持购买记录追踪与显隐切换 3. 重构ItemListComp为通用商店列表组件,适配装备与商品两种商店类型
This commit is contained in:
@@ -42,6 +42,7 @@ import { GameEvent } from "../common/config/GameEvent";
|
||||
import { CardConfig, CardPoolList, CardType, drawCardsByRule, SpecialRefreshCardList, SpecialRefreshHeroType, SpecialUpgradeCardList } from "../common/config/CardSet";
|
||||
import { drawSkillCards } from "../common/config/SCardSet";
|
||||
import { EquipPoolList } from "../common/config/EquipSet";
|
||||
import { ItemCardList, drawItemCards } from "../common/config/ICardSet";
|
||||
import { CardComp } from "./CardComp";
|
||||
import { SCardComp } from "./SCardComp";
|
||||
import { EquipListComp } from "./EquipListComp";
|
||||
@@ -53,6 +54,7 @@ import { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { FacSet, FightSet } from "../common/config/GameSet";
|
||||
import { MissionEconomy } from "./MissionEconomy";
|
||||
import { UIID } from "../common/config/GameUIConfig";
|
||||
import { ItemListComp } from "./ItemListComp";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -175,6 +177,8 @@ export class MissionCardComp extends CCComp {
|
||||
private skillCardComps: SCardComp[] = [];
|
||||
/** 已购买装备的 UUID 集合(跨波次保持,防止重复购买) */
|
||||
private purchasedEquipUuids: Set<number> = new Set();
|
||||
/** 已购买商品的 UUID 集合(跨波次保持,防止重复购买) */
|
||||
private purchasedItemUuids: Set<number> = new Set();
|
||||
/** 是否已缓存卡牌面板基准缩放 */
|
||||
private hasCachedCardsBaseScale: boolean = false;
|
||||
/** 卡牌面板基准缩放(从场景读取) */
|
||||
@@ -236,6 +240,12 @@ export class MissionCardComp extends CCComp {
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -282,6 +292,10 @@ export class MissionCardComp extends CCComp {
|
||||
this.purchasedEquipUuids.clear();
|
||||
this.populateEquipments();
|
||||
|
||||
// 重置商品购买记录并填充商品商店
|
||||
this.purchasedItemUuids.clear();
|
||||
this.populateShopItems();
|
||||
|
||||
// 首次进入准备阶段自动抽取一次技能卡,后续刷新只能通过技能刷新按钮触发
|
||||
this.initSkillCardsOnce();
|
||||
|
||||
@@ -292,6 +306,7 @@ export class MissionCardComp extends CCComp {
|
||||
onMissionEnd() {
|
||||
this.clearAllCards();
|
||||
this.clearEquipments();
|
||||
this.clearShopItems();
|
||||
if (this.node && this.node.isValid) {
|
||||
this.node.active = false;
|
||||
}
|
||||
@@ -337,6 +352,8 @@ export class MissionCardComp extends CCComp {
|
||||
oops.message.on(GameEvent.UseSkillCard, this.onUseSkillCard, this);
|
||||
// 监听装备购买事件,追踪已购记录
|
||||
oops.message.on(GameEvent.UseEquipCard, this.onUseEquipCard, this);
|
||||
// 监听商品购买事件,追踪已购记录
|
||||
oops.message.on(GameEvent.UseItemCard, this.onUseItemCard, this);
|
||||
oops.message.on(GameEvent.UseSpecialCard, this.onUseSpecialCard, this);
|
||||
oops.message.on(GameEvent.ShowSmallTip, this.onShowSmallTip, this);
|
||||
oops.message.on(GameEvent.CardUsed, this.onCardUsed, this);
|
||||
@@ -361,6 +378,11 @@ export class MissionCardComp extends CCComp {
|
||||
/** 关闭技能卡池按钮 */
|
||||
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);
|
||||
this.skill_refresh?.on(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, this);
|
||||
@@ -512,6 +534,70 @@ export class MissionCardComp extends CCComp {
|
||||
this.skill_card_node.active = false;
|
||||
}
|
||||
|
||||
// ======================== 商店面板 ========================
|
||||
|
||||
/**
|
||||
* 商店显隐切换按钮回调:
|
||||
* 切换 shopPanNode 的 active 状态。
|
||||
*/
|
||||
private onShowShopClick() {
|
||||
if (!this.shopPanNode || !this.shopPanNode.isValid) return;
|
||||
oops.audio.playEffect("music/button");
|
||||
this.shopPanNode.active = !this.shopPanNode.active;
|
||||
}
|
||||
|
||||
/** 关闭商店按钮回调 */
|
||||
private onCloseShopClick() {
|
||||
if (!this.shopPanNode || !this.shopPanNode.isValid) return;
|
||||
oops.audio.playEffect("music/button");
|
||||
this.shopPanNode.active = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充商品列表:
|
||||
* 从 ICardSet 的 ItemCardList 获取所有商品卡,
|
||||
* 实例化 itemPrefab 到 shopBoxNode,
|
||||
* 每个商品项由 ItemListComp 渲染并处理购买。
|
||||
*
|
||||
* 商品为一次性 buff 技能(Instant 触发,t_times=1),
|
||||
* 购买后立即生效,由 MissSkillsComp 统一处理技能逻辑。
|
||||
*/
|
||||
private populateShopItems() {
|
||||
if (!this.shopBoxNode || !this.itemPrefab) return;
|
||||
|
||||
// 清空旧列表
|
||||
this.shopBoxNode.removeAllChildren();
|
||||
|
||||
// 从商品卡池获取所有商品
|
||||
for (const item of ItemCardList) {
|
||||
const node = instantiate(this.itemPrefab);
|
||||
this.shopBoxNode.addChild(node);
|
||||
const comp = node.getComponent(ItemListComp) || node.addComponent(ItemListComp);
|
||||
comp.applyCardData(item);
|
||||
|
||||
// 已购买的商品标记为已购
|
||||
if (this.purchasedItemUuids.has(item.uuid)) {
|
||||
comp.setPurchased();
|
||||
}
|
||||
}
|
||||
|
||||
// 默认显示商店面板
|
||||
if (this.shopPanNode) {
|
||||
this.shopPanNode.active = true;
|
||||
}
|
||||
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "populate shop items", {
|
||||
count: ItemCardList.length
|
||||
});
|
||||
}
|
||||
|
||||
/** 清空商品列表 */
|
||||
private clearShopItems() {
|
||||
if (this.shopBoxNode && this.shopBoxNode.isValid) {
|
||||
this.shopBoxNode.removeAllChildren();
|
||||
}
|
||||
}
|
||||
|
||||
private dispatchCardsToSkillSlots(cards: CardConfig[]) {
|
||||
if (!this.skillCardComps) return;
|
||||
for (let i = 0; i < this.skillCardComps.length; i++) {
|
||||
@@ -548,6 +634,14 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
/** 商品购买事件回调:记录已购 UUID,防止重复购买 */
|
||||
private onUseItemCard(event: string, args: any) {
|
||||
const usedCard = args as CardConfig;
|
||||
if (usedCard) {
|
||||
this.purchasedItemUuids.add(usedCard.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
/** 解除按钮监听,避免节点销毁后回调泄漏 */
|
||||
private unbindEvents() {
|
||||
oops.message.off(GameEvent.CoinAdd, this.onCoinAdd, this);
|
||||
@@ -557,6 +651,7 @@ export class MissionCardComp extends CCComp {
|
||||
oops.message.off(GameEvent.UseHeroCard, this.onUseHeroCard, this);
|
||||
oops.message.off(GameEvent.UseSkillCard, this.onUseSkillCard, this);
|
||||
oops.message.off(GameEvent.UseEquipCard, this.onUseEquipCard, this);
|
||||
oops.message.off(GameEvent.UseItemCard, this.onUseItemCard, this);
|
||||
oops.message.off(GameEvent.UseSpecialCard, this.onUseSpecialCard, this);
|
||||
oops.message.off(GameEvent.ShowSmallTip, this.onShowSmallTip, this);
|
||||
oops.message.off(GameEvent.CardUsed, this.onCardUsed, this);
|
||||
@@ -587,6 +682,12 @@ export class MissionCardComp extends CCComp {
|
||||
this.skill_ad_refresh.off(NodeEventType.TOUCH_END, this.onSkillAdDrawTouchEnd, this);
|
||||
this.skill_ad_refresh.off(NodeEventType.TOUCH_CANCEL, this.onSkillAdDrawTouchCancel, 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1467,6 +1568,7 @@ export class MissionCardComp extends CCComp {
|
||||
this.cardComps = [] as any;
|
||||
this.skillCardComps = [] as any;
|
||||
this.purchasedEquipUuids.clear();
|
||||
this.purchasedItemUuids.clear();
|
||||
|
||||
if (this.node && this.node.isValid) {
|
||||
this.node.destroy();
|
||||
|
||||
Reference in New Issue
Block a user