From 5c5954b7d5116df68701c1427843583da4f1b880 Mon Sep 17 00:00:00 2001 From: panw Date: Wed, 14 Jan 2026 20:37:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=8D=A1=E7=89=8C=E7=B3=BB=E7=BB=9F):=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=8D=A1=E7=89=8C=E9=80=89=E6=8B=A9=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=B1=9E=E6=80=A7=E5=8D=A1?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在GameSet枚举中添加Attr卡牌类型 - 在GameEvent中添加UseAttrCard事件 - 重构CardSet模块,统一使用GameSet中的CardType枚举 - 重构MissionCardComp模块,支持混合模式卡牌选择和强制类型获取 - 添加等级升级事件处理,优化卡牌获取逻辑 --- assets/script/game/common/config/CardSet.ts | 26 +-- assets/script/game/common/config/GameEvent.ts | 1 + assets/script/game/common/config/GameSet.ts | 3 +- assets/script/game/map/MissionCardComp.ts | 186 ++++++++++-------- 4 files changed, 116 insertions(+), 100 deletions(-) diff --git a/assets/script/game/common/config/CardSet.ts b/assets/script/game/common/config/CardSet.ts index dddbc65f..8ddea113 100644 --- a/assets/script/game/common/config/CardSet.ts +++ b/assets/script/game/common/config/CardSet.ts @@ -2,16 +2,7 @@ import { AttrCards, AttrInfo, CanSelectAttrs } from "./AttrSet"; import { talConf, ItalConf, CanSelectTalents } from "./TalSet"; import { SkillSet, SkillConfig, CanSelectSkills } from "./SkillSet"; import { HeroInfo, heroInfo, CanSelectHeros } from "./heroSet"; - -/** - * 卡牌类型枚举 - */ -export enum CardType { - Skill = 1, // 技能 - Talent = 2, // 天赋 - Attr = 3, // 属性 - Hero = 4 // 英雄(伙伴) -} +import { CardType } from "./GameSet"; /** * 统一卡牌信息接口 (用于UI显示和逻辑处理) @@ -58,7 +49,7 @@ export const LevelPoolConfigs: Record = { 3: [{ type: CardType.Talent, poolWeight: 50 }, { type: CardType.Attr, poolWeight: 50, tag: "special" }], // 天赋或特殊属性 4: [{ type: CardType.Attr, poolWeight: 100 }], 5: [{ type: CardType.Talent, poolWeight: 100 }], - 6: [{ type: CardType.Hero, poolWeight: 100 }], // 伙伴节点 + 6: [{ type: CardType.Partner, poolWeight: 100 }], // 伙伴节点 7: [{ type: CardType.Attr, poolWeight: 80 }, { type: CardType.Skill, poolWeight: 20 }], 8: [{ type: CardType.Attr, poolWeight: 80 }, { type: CardType.Skill, poolWeight: 20 }], 9: [{ type: CardType.Attr, poolWeight: 50, tag: "special" }, { type: CardType.Talent, poolWeight: 50 }], @@ -110,7 +101,7 @@ function getCardBaseInfo(type: CardType, uuid: number): ICardInfo | null { desc = baseInfo.info; icon = baseInfo.icon; break; - case CardType.Hero: + case CardType.Partner: baseInfo = HeroInfo[uuid]; if (!baseInfo) return null; name = baseInfo.name; @@ -175,7 +166,7 @@ function getDefaultPool(type: CardType, level: number = 1): IPoolItem[] { Object.keys(SkillSet).forEach(key => items.push({ id: Number(key), weight: 80 })); } break; - case CardType.Hero: + case CardType.Partner: // 优先使用 CanSelectHeros 中的配置 if (CanSelectHeros[level]) { CanSelectHeros[level].forEach(id => items.push({ id, weight: 100 })); @@ -199,11 +190,14 @@ function getDefaultPool(type: CardType, level: number = 1): IPoolItem[] { * @param level 当前等级 * @param count 选项数量 (默认3个) * @param excludeUuids 排除的卡牌UUID列表 (用于去重或排除已拥有) + * @param forcedType 强制指定卡牌类型 (用于特殊获取,如商店、技能书等) */ -export function getCardOptions(level: number, count: number = 3, excludeUuids: number[] = []): ICardInfo[] { +export function getCardOptions(level: number, count: number = 3, excludeUuids: number[] = [], forcedType?: CardType): ICardInfo[] { // 1. 获取该等级的池配置 - // 必须复制一份,因为我们可能需要修改它(比如移除空的池子) - const initialPoolConfigs = LevelPoolConfigs[level] || [{ type: CardType.Attr, poolWeight: 100 }]; + // 如果强制指定类型,则构造一个只包含该类型的配置 + const initialPoolConfigs = forcedType + ? [{ type: forcedType, poolWeight: 100 }] + : (LevelPoolConfigs[level] || [{ type: CardType.Attr, poolWeight: 100 }]); const result: ICardInfo[] = []; const excludeSet = new Set(excludeUuids); diff --git a/assets/script/game/common/config/GameEvent.ts b/assets/script/game/common/config/GameEvent.ts index 995e97cd..c8fa706d 100644 --- a/assets/script/game/common/config/GameEvent.ts +++ b/assets/script/game/common/config/GameEvent.ts @@ -49,6 +49,7 @@ export enum GameEvent { TalentSelect = "TalentSelect", UseTalentCard = "UseTalentCard", UseItemCard = "UseItemCard", + UseAttrCard = "UseAttrCard", NewWave = "NewWave", AD_BACK_TRUE = "AD_BACK_TRUE", AD_BACK_FALSE = "AD_BACK_FALSE", diff --git a/assets/script/game/common/config/GameSet.ts b/assets/script/game/common/config/GameSet.ts index c8755d06..8cc29428 100644 --- a/assets/script/game/common/config/GameSet.ts +++ b/assets/script/game/common/config/GameSet.ts @@ -26,7 +26,8 @@ export enum CardType { Talent = 1, Skill = 2, Potion = 3, - Partner = 4 + Partner = 4, + Attr = 5 } /** diff --git a/assets/script/game/map/MissionCardComp.ts b/assets/script/game/map/MissionCardComp.ts index 015b7cf4..6fa357da 100644 --- a/assets/script/game/map/MissionCardComp.ts +++ b/assets/script/game/map/MissionCardComp.ts @@ -3,15 +3,17 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; import { GameEvent } from "../common/config/GameEvent"; -import { talConf, ItalConf } from "../common/config/TalSet"; -import { CanSelectHeros, HeroInfo } from "../common/config/heroSet"; -import { CanSelectSkills, SkillSet } from "../common/config/SkillSet"; -import { ItemSet } from "../common/config/ItemSet"; import { smc } from "../common/SingletonModuleComp"; import { CardType } from "../common/config/GameSet"; +import { getCardOptions, ICardInfo } from "../common/config/CardSet"; const { ccclass, property } = _decorator; +interface ICardEvent { + type?: CardType; + level?: number; +} + /** 视图层对象 */ @ccclass('MissionCardComp') @ecs.register('MissionCard', false) @@ -36,13 +38,13 @@ export class MissionCardComp extends CCComp { @property(Node) noStop: Node = null! - card1_data:any = null! - card2_data:any = null! - card3_data:any = null! - card4_data:any = null! + card1_data: ICardInfo = null! + card2_data: ICardInfo = null! + card3_data: ICardInfo = null! + card4_data: ICardInfo = null! - // 当前卡片类型 - curCardType: CardType = CardType.Talent; + // 当前卡片类型 (用于特殊获取模式) + curCardType: CardType | null = null; // 是否处于锁定状态 private isLocked: boolean = true; @@ -60,6 +62,7 @@ export class MissionCardComp extends CCComp { oops.message.on(GameEvent.MissionStart, this.onMissionStart, this); oops.message.on(GameEvent.MissionEnd, this.onMissionEnd, this); oops.message.on(GameEvent.ToCallFriend, this.onCallFriend, this); + oops.message.on(GameEvent.CanUpdateLv, this.onLevelUp, this); } @@ -74,6 +77,7 @@ export class MissionCardComp extends CCComp { oops.message.off(GameEvent.MissionStart, this.onMissionStart, this); oops.message.off(GameEvent.MissionEnd, this.onMissionEnd, this); oops.message.off(GameEvent.ToCallFriend, this.onCallFriend, this); + oops.message.off(GameEvent.CanUpdateLv, this.onLevelUp, this); this.ent.destroy(); } @@ -130,25 +134,31 @@ export class MissionCardComp extends CCComp { private hasSelected: boolean = false; // 事件队列 - private eventQueue: CardType[] = []; + private eventQueue: ICardEvent[] = []; private onShopOpen(event: string, args: any) { - this.eventQueue.push(CardType.Potion); + this.eventQueue.push({ type: CardType.Potion }); this.checkQueue(); } private onTalentSelect(event: string, args: any) { - this.eventQueue.push(CardType.Talent); + this.eventQueue.push({ type: CardType.Talent }); this.checkQueue(); } private onHeroSkillSelect(event: string, args: any) { - this.eventQueue.push(CardType.Skill); + this.eventQueue.push({ type: CardType.Skill }); this.checkQueue(); } private onCallFriend(event: string, args: any) { - this.eventQueue.push(CardType.Partner); + this.eventQueue.push({ type: CardType.Partner }); + this.checkQueue(); + } + + private onLevelUp(event: string, args: any) { + // args.lv 是当前等级 + this.eventQueue.push({ level: args.lv }); this.checkQueue(); } @@ -156,18 +166,42 @@ export class MissionCardComp extends CCComp { if (this.node.active) return; if (this.eventQueue.length === 0) return; - const type = this.eventQueue.shift(); - if (type) { - this.showCardType(type); + const event = this.eventQueue.shift(); + if (event) { + if (event.type !== undefined) { + this.showCardType(event.type); + } else if (event.level !== undefined) { + this.showLevelCards(event.level); + } } } + /** + * 显示指定类型的卡牌(特殊获取模式) + */ private showCardType(type: CardType) { + this.curCardType = type; + // 获取当前英雄等级作为参考,或者默认1级 + const level = smc.vmdata.hero.lv || 1; + this.fetchCards(level, type); + this.openUI(); + } + + /** + * 显示等级对应的卡牌(正常升级模式) + */ + private showLevelCards(level: number) { + this.curCardType = null; // 混合模式,无单一类型 + this.fetchCards(level); + this.openUI(); + } + + private openUI() { this.node.active = true; this.hasSelected = false; - this.curCardType = type; - // 根据锁定状态显示 Lock 节点 + // 根据锁定状态显示 Lock 节点 (仅在特殊模式下可能需要锁定?或者统一逻辑) + // 原逻辑:Lock.active = this.isLocked if (this.Lock) { this.Lock.active = this.isLocked; } @@ -184,9 +218,9 @@ export class MissionCardComp extends CCComp { } this.resetCardStates(); - this.refCards(); this.playShowAnimation(); } + checkNoStop(){ this.noStop.getChildByName("no").active=!smc.data.noStop @@ -212,42 +246,30 @@ export class MissionCardComp extends CCComp { }); } - refCards(){ - // 根据当前类型获取数据 - let allData: any[] = []; - - if (this.curCardType === CardType.Talent) { - allData = Object.values(talConf); - } else if (this.curCardType === CardType.Skill) { - // 过滤掉怪物技能 (uuid >= 6200) - // allData = Object.values(SkillSet).filter((s:any) => s.uuid < 6200); - allData = CanSelectSkills.map(id => SkillSet[id]); - } else if (this.curCardType === CardType.Partner) { - allData = CanSelectHeros.map(id => HeroInfo[id]); - } else if (this.curCardType === CardType.Potion) { - allData = Object.values(ItemSet); - } - // 后续扩展其他类型 - // else if (this.curCardType === CardType.Skill) { ... } + /** + * 专门的获取卡牌方法 + * @param level 等级 + * @param forcedType 强制类型 (可选) + */ + fetchCards(level: number, forcedType?: CardType){ + // 使用 CardSet 的 getCardOptions 获取卡牌 + // 这里我们要获取 4 张卡牌 + const options = getCardOptions(level, 4, [], forcedType); - const result: any[] = []; - const temp = [...allData]; + // 更新卡片数据 + if (options.length > 0) this.updateCardData(1, options[0]); + if (options.length > 1) this.updateCardData(2, options[1]); + if (options.length > 2) this.updateCardData(3, options[2]); + if (options.length > 3) this.updateCardData(4, options[3]); - // 简单的随机抽取算法 - for (let i = 0; i < 4 && temp.length > 0; i++) { - const index = Math.floor(Math.random() * temp.length); - result.push(temp[index]); - temp.splice(index, 1); - } - - // 更新卡片 - if (result.length > 0) this.updateCardData(1, result[0]); - if (result.length > 1) this.updateCardData(2, result[1]); - if (result.length > 2) this.updateCardData(3, result[2]); - if (result.length > 3) this.updateCardData(4, result[3]); + // 如果获取不足4张,隐藏多余的卡片节点 (UI可能需要处理空数据) + if (options.length < 4 && this.card4) this.card4.active = false; + if (options.length < 3 && this.card3) this.card3.active = false; + if (options.length < 2 && this.card2) this.card2.active = false; + if (options.length < 1 && this.card1) this.card1.active = false; } - updateCardInfo(card:Node, data:any){ + updateCardInfo(card:Node, data: ICardInfo){ if(!card) return card.active = true; // 隐藏选中状态 @@ -260,24 +282,13 @@ export class MissionCardComp extends CCComp { } let info = card.getChildByName("info")?.getChildByName("Label") if(info){ - // 根据类型显示不同描述,目前天赋用desc - let desc = ""; - if (this.curCardType === CardType.Talent) { - desc = data.desc || ""; - } else if (this.curCardType === CardType.Skill) { - desc = data.info || ""; - } else if (this.curCardType === CardType.Partner) { - desc = data.info || ""; - } else { - desc = data.desc || ""; - } - - info.getComponent(Label)!.string = desc; + // ICardInfo 已经标准化了 desc,直接使用 + info.getComponent(Label)!.string = data.desc || ""; } } - updateCardData(index: number, data: any) { - // 使用动态属性访问,简化 switch 冗余代码 + updateCardData(index: number, data: ICardInfo) { + // 使用动态属性访问 (this as any)[`card${index}_data`] = data; this.updateCardInfo((this as any)[`card${index}`], data); } @@ -288,13 +299,13 @@ export class MissionCardComp extends CCComp { // 如果已经选择过,则不再处理 if (this.hasSelected) return; - // 动态获取数据和节点,简化 switch 逻辑 - let selectedData: any = (this as any)[`card${_index}_data`]; + // 动态获取数据和节点 + let selectedData: ICardInfo = (this as any)[`card${_index}_data`]; let selectedCardNode: Node | null = (this as any)[`card${_index}`]; if (selectedData && selectedCardNode) { this.hasSelected = true; - console.log("选择卡片:", selectedData.name, "类型:", this.curCardType); + console.log("选择卡片:", selectedData.name, "类型:", selectedData.type); // 未选中的卡片缩小 const cards = [this.card1, this.card2, this.card3, this.card4]; @@ -319,18 +330,27 @@ export class MissionCardComp extends CCComp { .delay(0.5) .call(() => { // 根据类型发送不同事件 - if (this.curCardType === CardType.Talent) { - smc.addTalentRecord(selectedData.uuid); - oops.message.dispatchEvent(GameEvent.UseTalentCard, selectedData.uuid); - } else if (this.curCardType === CardType.Skill) { - smc.addSkillRecord(selectedData.uuid); - oops.message.dispatchEvent(GameEvent.UseSkillCard, selectedData.uuid); - } else if (this.curCardType === CardType.Partner) { - oops.message.dispatchEvent(GameEvent.CallFriend, { uuid: selectedData.uuid }); - } else if (this.curCardType === CardType.Potion) { - oops.message.dispatchEvent(GameEvent.UseItemCard, selectedData.id); + switch (selectedData.type) { + case CardType.Talent: + smc.addTalentRecord(selectedData.uuid); + oops.message.dispatchEvent(GameEvent.UseTalentCard, selectedData.uuid); + break; + case CardType.Skill: + smc.addSkillRecord(selectedData.uuid); + oops.message.dispatchEvent(GameEvent.UseSkillCard, selectedData.uuid); + break; + case CardType.Partner: + oops.message.dispatchEvent(GameEvent.CallFriend, { uuid: selectedData.uuid }); + break; + case CardType.Potion: + // Potion 在 CardSet 中也是 uuid + oops.message.dispatchEvent(GameEvent.UseItemCard, selectedData.uuid); + break; + case CardType.Attr: + oops.message.dispatchEvent(GameEvent.UseAttrCard, selectedData.uuid); + break; } - // 后续扩展其他类型事件 + this.close(); }) .start(); @@ -449,4 +469,4 @@ export class MissionCardComp extends CCComp { reset() { this.node.destroy(); } -} \ No newline at end of file +}