feat(mission): 新增装备和商店刷新功能,重构抽卡逻辑
1. 新增按权重抽取装备卡的工具函数,支持去重后补齐 2. 重构任务界面卡牌组件: - 拆分英雄/装备/商店面板节点绑定,调整属性顺序 - 新增装备和商店刷新按钮的交互逻辑 - 替换原固定加载装备/商品列表为按权重随机抽取3个 3. 重构技能卡牌组件,改为技能商店卡项实现,简化原有逻辑 4. 修复prefab中的节点属性偏移和引用关系
This commit is contained in:
@@ -41,8 +41,8 @@ import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/modu
|
||||
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 { drawEquipCards } from "../common/config/EquipSet";
|
||||
import { drawItemCards } from "../common/config/ICardSet";
|
||||
import { CardComp } from "./CardComp";
|
||||
import { SCardComp } from "./SCardComp";
|
||||
import { EquipListComp } from "./EquipListComp";
|
||||
@@ -85,7 +85,9 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
// ======================== 编辑器绑定节点 ========================
|
||||
|
||||
/** 卡牌面板根节点(战斗阶段收起,准备阶段展开) */
|
||||
/** 英雄卡牌面板根节点(战斗阶段收起,准备阶段展开) */
|
||||
@property(Node)
|
||||
showCards: Node = null!
|
||||
@property(Node)
|
||||
cards_node: Node = null!
|
||||
/** 卡牌槽位 1 节点 */
|
||||
@@ -97,36 +99,47 @@ export class MissionCardComp extends CCComp {
|
||||
/** 卡牌槽位 3 节点 */
|
||||
@property(Node)
|
||||
card3: Node = null!
|
||||
/** 卡牌槽位 4 节点 */
|
||||
@property(Node)
|
||||
card4: Node = null!
|
||||
/** 抽卡(刷新)按钮节点 */
|
||||
@property(Node)
|
||||
cards_chou: Node = null!
|
||||
@property(Node)
|
||||
nock_node: Node = null!
|
||||
|
||||
/** 英雄卡牌池cards_node显示隐藏 */
|
||||
|
||||
/** 英雄面板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)
|
||||
showSkills: Node = null!
|
||||
@property(Node)
|
||||
closeSkills: 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)
|
||||
@@ -138,6 +151,7 @@ export class MissionCardComp extends CCComp {
|
||||
@property(Prefab)
|
||||
itemPrefab: Prefab = null!
|
||||
/** 卡池升级按钮节点(已废弃,保留节点引用防止 editor 报错) */
|
||||
|
||||
@property(Node)
|
||||
cards_up: Node = null!
|
||||
/** 金币显示节点(含 icon + num 子节点) */
|
||||
@@ -171,6 +185,13 @@ export class MissionCardComp extends CCComp {
|
||||
@property(Node)
|
||||
skill_refresh_num_node: Node = null!
|
||||
|
||||
/** 装备刷新按钮节点 */
|
||||
@property(Node)
|
||||
equip_refresh: Node = null!;
|
||||
/** 药品刷新按钮节点 */
|
||||
@property(Node)
|
||||
shop_refresh: Node = null!;
|
||||
|
||||
// ======================== 运行时状态 ========================
|
||||
|
||||
/** 三个槽位对应的 CardComp 控制器缓存(有序数组) */
|
||||
@@ -413,6 +434,16 @@ export class MissionCardComp extends CCComp {
|
||||
this.skill_ad_refresh?.on(NodeEventType.TOUCH_START, this.onSkillAdDrawTouchStart, this);
|
||||
this.skill_ad_refresh?.on(NodeEventType.TOUCH_END, this.onSkillAdDrawTouchEnd, this);
|
||||
this.skill_ad_refresh?.on(NodeEventType.TOUCH_CANCEL, this.onSkillAdDrawTouchCancel, this);
|
||||
|
||||
/** 装备刷新按钮 */
|
||||
this.equip_refresh?.on(NodeEventType.TOUCH_START, this.onEquipDrawTouchStart, this);
|
||||
this.equip_refresh?.on(NodeEventType.TOUCH_END, this.onEquipDrawTouchEnd, this);
|
||||
this.equip_refresh?.on(NodeEventType.TOUCH_CANCEL, this.onEquipDrawTouchCancel, this);
|
||||
|
||||
/** 药品刷新按钮 */
|
||||
this.shop_refresh?.on(NodeEventType.TOUCH_START, this.onShopDrawTouchStart, this);
|
||||
this.shop_refresh?.on(NodeEventType.TOUCH_END, this.onShopDrawTouchEnd, this);
|
||||
this.shop_refresh?.on(NodeEventType.TOUCH_CANCEL, this.onShopDrawTouchCancel, this);
|
||||
}
|
||||
// ======================== 事件回调 ========================
|
||||
|
||||
@@ -565,7 +596,7 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 填充商品列表:
|
||||
* 从 ICardSet 的 ItemCardList 获取所有商品卡,
|
||||
* 从 ICardSet 按权重抽取 3 张商品卡,
|
||||
* 实例化 itemPrefab 到 shopBoxNode,
|
||||
* 每个商品项由 ItemListComp 渲染并处理购买。
|
||||
*
|
||||
@@ -578,8 +609,9 @@ export class MissionCardComp extends CCComp {
|
||||
// 清空旧列表
|
||||
this.shopBoxNode.removeAllChildren();
|
||||
|
||||
// 从商品卡池获取所有商品
|
||||
for (const item of ItemCardList) {
|
||||
// 从商品卡池按权重抽取 3 张
|
||||
const items = drawItemCards(3);
|
||||
for (const item of items) {
|
||||
const node = instantiate(this.itemPrefab);
|
||||
this.shopBoxNode.addChild(node);
|
||||
const comp = node.getComponent(ItemListComp) || node.addComponent(ItemListComp);
|
||||
@@ -592,7 +624,7 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
// 根据物品数量设置列表面板高度
|
||||
this.resizeListBox(this.shopBoxNode, ItemCardList.length);
|
||||
this.resizeListBox(this.shopBoxNode, items.length);
|
||||
|
||||
// 默认显示商店面板
|
||||
if (this.shopPanNode) {
|
||||
@@ -600,7 +632,7 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "populate shop items", {
|
||||
count: ItemCardList.length
|
||||
count: items.length
|
||||
});
|
||||
}
|
||||
|
||||
@@ -615,7 +647,7 @@ export class MissionCardComp extends CCComp {
|
||||
if (!this.skillCardComps) return;
|
||||
for (let i = 0; i < this.skillCardComps.length; i++) {
|
||||
if (this.skillCardComps[i]) {
|
||||
this.skillCardComps[i].applyDrawCard(cards[i] ?? null);
|
||||
this.skillCardComps[i].applyCardData(cards[i] ?? null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -701,6 +733,16 @@ export class MissionCardComp extends CCComp {
|
||||
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);
|
||||
this.equip_refresh.off(NodeEventType.TOUCH_CANCEL, this.onEquipDrawTouchCancel, this);
|
||||
}
|
||||
if (this.shop_refresh && this.shop_refresh.isValid) {
|
||||
this.shop_refresh.off(NodeEventType.TOUCH_START, this.onShopDrawTouchStart, this);
|
||||
this.shop_refresh.off(NodeEventType.TOUCH_END, this.onShopDrawTouchEnd, this);
|
||||
this.shop_refresh.off(NodeEventType.TOUCH_CANCEL, this.onShopDrawTouchCancel, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1025,7 +1067,7 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 填充装备列表:
|
||||
* 从 CardPoolList 获取所有装备卡(trigger_type=Field),
|
||||
* 从 EquipPoolList 按权重抽取 3 张装备卡,
|
||||
* 实例化 equipPrefab 到 equipsBoxNode,
|
||||
* 每个装备项由 EquipListComp 渲染并处理购买。
|
||||
*
|
||||
@@ -1037,8 +1079,9 @@ export class MissionCardComp extends CCComp {
|
||||
// 清空旧列表
|
||||
this.equipsBoxNode.removeAllChildren();
|
||||
|
||||
// 从独立装备卡池获取所有装备
|
||||
for (const equip of EquipPoolList) {
|
||||
// 从装备卡池按权重抽取 3 张
|
||||
const equips = drawEquipCards(3);
|
||||
for (const equip of equips) {
|
||||
const node = instantiate(this.equipPrefab);
|
||||
this.equipsBoxNode.addChild(node);
|
||||
const comp = node.getComponent(EquipListComp) || node.addComponent(EquipListComp);
|
||||
@@ -1051,7 +1094,7 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
// 根据物品数量设置列表面板高度
|
||||
this.resizeListBox(this.equipsBoxNode, EquipPoolList.length);
|
||||
this.resizeListBox(this.equipsBoxNode, equips.length);
|
||||
|
||||
// 默认显示装备面板
|
||||
if (this.equipsPanNode) {
|
||||
@@ -1059,7 +1102,7 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "populate equipments", {
|
||||
count: EquipPoolList.length
|
||||
count: equips.length
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1110,11 +1153,54 @@ export class MissionCardComp extends CCComp {
|
||||
this.dispatchCardsToSkillSlots(cards);
|
||||
}
|
||||
|
||||
// ======================== 装备/药品刷新按钮回调 ========================
|
||||
|
||||
private onEquipDrawTouchStart() {
|
||||
this.playButtonPressAnim(this.equip_refresh);
|
||||
}
|
||||
private onEquipDrawTouchEnd() {
|
||||
oops.audio.playEffect("music/button");
|
||||
this.playButtonClickAnim(this.equip_refresh, () => this.onClickEquipRefresh());
|
||||
}
|
||||
private onEquipDrawTouchCancel() {
|
||||
this.playButtonResetAnim(this.equip_refresh);
|
||||
}
|
||||
|
||||
private onShopDrawTouchStart() {
|
||||
this.playButtonPressAnim(this.shop_refresh);
|
||||
}
|
||||
private onShopDrawTouchEnd() {
|
||||
oops.audio.playEffect("music/button");
|
||||
this.playButtonClickAnim(this.shop_refresh, () => this.onClickShopRefresh());
|
||||
}
|
||||
private onShopDrawTouchCancel() {
|
||||
this.playButtonResetAnim(this.shop_refresh);
|
||||
}
|
||||
|
||||
/** 装备刷新:扣费后重新抽取 3 张装备展示 */
|
||||
private onClickEquipRefresh() {
|
||||
const cost = MissionEconomy.getRefreshCost(this.refreshCost);
|
||||
const success = MissionEconomy.executeRefresh(this.refreshCost);
|
||||
if (!success) {
|
||||
this.showSmallTip("refresh_coin");
|
||||
return;
|
||||
}
|
||||
this.populateEquipments();
|
||||
}
|
||||
|
||||
/** 药品刷新:扣费后重新抽取 3 张商品展示 */
|
||||
private onClickShopRefresh() {
|
||||
const cost = MissionEconomy.getRefreshCost(this.refreshCost);
|
||||
const success = MissionEconomy.executeRefresh(this.refreshCost);
|
||||
if (!success) {
|
||||
this.showSmallTip("refresh_coin");
|
||||
return;
|
||||
}
|
||||
this.populateShopItems();
|
||||
}
|
||||
|
||||
/** 将三个卡槽节点映射为 CardComp,形成固定顺序控制数组 */
|
||||
private cacheCardComps() {
|
||||
if (this.card4) {
|
||||
this.card4.active = false;
|
||||
}
|
||||
const nodes = [this.card1, this.card2, this.card3];
|
||||
this.cardComps = nodes
|
||||
.map(node => node?.getComponent(CardComp))
|
||||
@@ -1431,7 +1517,7 @@ export class MissionCardComp extends CCComp {
|
||||
});
|
||||
if (this.skillCardComps) {
|
||||
this.skillCardComps.forEach(comp => {
|
||||
if (comp) comp.clearBySystem();
|
||||
if (comp) comp.applyCardData(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1502,6 +1588,30 @@ export class MissionCardComp extends CCComp {
|
||||
numLabel.string = `${MissionEconomy.getRefreshCost(this.refreshCost)}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.equip_refresh) {
|
||||
const nobg = this.equip_refresh.getChildByName("nobg");
|
||||
if (nobg) {
|
||||
nobg.active = !this.canDrawCards();
|
||||
}
|
||||
const coinNode = this.equip_refresh.getChildByName("coin");
|
||||
const numLabel = coinNode?.getChildByName("num")?.getComponent(Label);
|
||||
if (numLabel) {
|
||||
numLabel.string = `${MissionEconomy.getRefreshCost(this.refreshCost)}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.shop_refresh) {
|
||||
const nobg = this.shop_refresh.getChildByName("nobg");
|
||||
if (nobg) {
|
||||
nobg.active = !this.canDrawCards();
|
||||
}
|
||||
const coinNode = this.shop_refresh.getChildByName("coin");
|
||||
const numLabel = coinNode?.getChildByName("num")?.getComponent(Label);
|
||||
if (numLabel) {
|
||||
numLabel.string = `${MissionEconomy.getRefreshCost(this.refreshCost)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private updateCoinAndCostUI() {
|
||||
|
||||
Reference in New Issue
Block a user