From e576d1925588383f81c59bd39ab00d0a4463d668 Mon Sep 17 00:00:00 2001 From: panw Date: Mon, 5 Jan 2026 09:54:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=89=A9=E5=93=81=E7=B3=BB=E7=BB=9F):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=89=A9=E5=93=81=E4=BD=BF=E7=94=A8=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在GameEvent枚举中添加UseItemCard事件 - 创建ItemSet物品配置表,包含8种不同效果的物品 - 在HeroAttrsComp中添加物品使用逻辑,处理物品效果应用 - 修改MissionCardComp支持物品购买界面和购买逻辑 - 添加物品购买后的视觉反馈和状态管理 --- assets/script/game/common/config/GameEvent.ts | 1 + assets/script/game/common/config/ItemSet.ts | 105 ++++++++++++++++++ assets/script/game/hero/HeroAttrsComp.ts | 43 ++++++- assets/script/game/map/MissionCardComp.ts | 72 +++++++++++- 4 files changed, 218 insertions(+), 3 deletions(-) diff --git a/assets/script/game/common/config/GameEvent.ts b/assets/script/game/common/config/GameEvent.ts index a98d496f..a6f3545b 100644 --- a/assets/script/game/common/config/GameEvent.ts +++ b/assets/script/game/common/config/GameEvent.ts @@ -48,6 +48,7 @@ export enum GameEvent { FuncSelect = "FuncSelect", TalentSelect = "TalentSelect", UseTalentCard = "UseTalentCard", + UseItemCard = "UseItemCard", NewWave = "NewWave", AD_BACK_TRUE = "AD_BACK_TRUE", AD_BACK_FALSE = "AD_BACK_FALSE", diff --git a/assets/script/game/common/config/ItemSet.ts b/assets/script/game/common/config/ItemSet.ts index e69de29b..45861e53 100644 --- a/assets/script/game/common/config/ItemSet.ts +++ b/assets/script/game/common/config/ItemSet.ts @@ -0,0 +1,105 @@ +import { Attrs, BType } from "./HeroAttrs"; + +/** + * 物品配置接口 + */ +export interface ItemConf { + id: number; + name: string; + desc: string; + price: number; + duration: number; // 持续时间(秒) + attr: Attrs; // 提升的属性 + value: number; // 提升的值 + bType: BType; // 值类型(数值/百分比) +} + +/** + * 物品配置表 + * 20秒强效果,60秒弱效果 + */ +export const ItemSet: Record = { + // ==================== 20秒强效果 (价格: 100) ==================== + 1001: { + id: 1001, + name: "狂暴药水", + desc: "20秒内攻击力+50%", + price: 100, + duration: 20, + attr: Attrs.AP, + value: 50, + bType: BType.RATIO + }, + 1002: { + id: 1002, + name: "急速药水", + desc: "20秒内攻速+50%", + price: 100, + duration: 20, + attr: Attrs.AS, + value: 50, + bType: BType.RATIO + }, + 1003: { + id: 1003, + name: "金钟罩", + desc: "20秒内防御+50%", + price: 100, + duration: 20, + attr: Attrs.DEF, + value: 50, + bType: BType.RATIO + }, + 1004: { + id: 1004, + name: "神行药水", + desc: "20秒内移速+50%", + price: 100, + duration: 20, + attr: Attrs.SPEED, + value: 50, + bType: BType.RATIO + }, + + // ==================== 60秒弱效果 (价格: 50) ==================== + 2001: { + id: 2001, + name: "力量药剂", + desc: "60秒内攻击力+20%", + price: 50, + duration: 60, + attr: Attrs.AP, + value: 20, + bType: BType.RATIO + }, + 2002: { + id: 2002, + name: "敏捷药剂", + desc: "60秒内攻速+20%", + price: 50, + duration: 60, + attr: Attrs.AS, + value: 20, + bType: BType.RATIO + }, + 2003: { + id: 2003, + name: "护甲药剂", + desc: "60秒内防御+20%", + price: 50, + duration: 60, + attr: Attrs.DEF, + value: 20, + bType: BType.RATIO + }, + 2004: { + id: 2004, + name: "轻灵药剂", + desc: "60秒内移速+20%", + price: 50, + duration: 60, + attr: Attrs.SPEED, + value: 20, + bType: BType.RATIO + }, +}; diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index 5053b801..521393cd 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -6,6 +6,7 @@ import { BuffConf } from "../common/config/SkillSet"; import { HeroInfo, AttrSet } from "../common/config/heroSet"; import { HeroSkillsComp } from "./HeroSkills"; import { smc } from "../common/SingletonModuleComp"; +import { ItemSet } from "../common/config/ItemSet"; interface talTrigger{ @@ -78,10 +79,17 @@ export class HeroAttrsComp extends ecs.Comp { onLoad() { // 监听升级事件 oops.message.on(GameEvent.CanUpdateLv, this.onLevelUp, this); + oops.message.on(GameEvent.UseItemCard, this.onUseItemCard, this); } onDestroy() { oops.message.off(GameEvent.CanUpdateLv, this.onLevelUp, this); + oops.message.off(GameEvent.UseItemCard, this.onUseItemCard, this); + } + + onUseItemCard(event: string, args: any) { + if (!this.is_master) return; + this.useItem(args); } /** @@ -579,9 +587,40 @@ export class HeroAttrsComp extends ecs.Comp { useValueTalByUuid(t_uuid: number) { const buff = this.BUFFS_TAL[t_uuid]; if (!buff) return; - const attrIndex = buff.attrIndex; - delete this.BUFFS_TAL[t_uuid]; + buff.count--; + if (buff.count <= 0) { + delete this.BUFFS_TAL[t_uuid]; + } + this.recalculateSingleAttr(buff.attrIndex); + } + + /** + * 使用物品 + * @param itemId 物品ID + */ + useItem(itemId: number) { + const item = ItemSet[itemId]; + if (!item) return; + + console.log(`[HeroAttrs] 使用物品: ${item.name} (${item.desc})`); + + // 直接添加到 BUFFS_TEMP + const attrIndex = item.attr; + + if (!this.BUFFS_TEMP[attrIndex]) { + this.BUFFS_TEMP[attrIndex] = []; + } + + this.BUFFS_TEMP[attrIndex].push({ + value: item.value, + BType: item.bType, + remainTime: item.duration + }); + + // 重新计算受影响的属性 this.recalculateSingleAttr(attrIndex); + + oops.gui.toast(`使用了 ${item.name}`); } /** diff --git a/assets/script/game/map/MissionCardComp.ts b/assets/script/game/map/MissionCardComp.ts index 1a44210b..52900000 100644 --- a/assets/script/game/map/MissionCardComp.ts +++ b/assets/script/game/map/MissionCardComp.ts @@ -1,9 +1,11 @@ -import { _decorator, Label, Node, tween, Vec3 } from "cc"; +import { _decorator, Label, Node, tween, Vec3, Color, Sprite } from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; 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 { ItemSet } from "../common/config/ItemSet"; +import { smc } from "../common/SingletonModuleComp"; const { ccclass, property } = _decorator; @@ -34,13 +36,18 @@ export class MissionCardComp extends CCComp { // 当前卡片类型 curCardType: CardType = CardType.Talent; + + // 已购买的卡片槽位标记 (用于物品购买) + purchasedSlots: boolean[] = [false, false, false, false, false]; onLoad() { oops.message.on(GameEvent.TalentSelect, this.onTalentSelect, this); + oops.message.on(GameEvent.ShopOpen, this.onShopOpen, this); } onDestroy() { oops.message.off(GameEvent.TalentSelect, this.onTalentSelect, this); + oops.message.off(GameEvent.ShopOpen, this.onShopOpen, this); this.ent.destroy(); } @@ -56,13 +63,28 @@ export class MissionCardComp extends CCComp { if (card) { const selected = card.getChildByName("selected"); if (selected) selected.active = false; + // 恢复缩放和颜色 + card.setScale(1, 1, 1); + const sprite = card.getComponent(Sprite); + if (sprite) sprite.color = new Color(255, 255, 255); } }); + // 重置购买状态 + this.purchasedSlots = [false, false, false, false, false]; } // 是否已经选择了天赋 private hasSelected: boolean = false; + private onShopOpen(event: string, args: any) { + this.node.active = true; + this.hasSelected = false; + this.curCardType = CardType.Potion; + this.resetCardStates(); + this.refCards(); + this.playShowAnimation(); + } + private onTalentSelect(event: string, args: any) { this.node.active = true; this.hasSelected = false; // 重置选择状态 @@ -180,6 +202,47 @@ export class MissionCardComp extends CCComp { } if (selectedData && selectedCardNode) { + // 处理物品购买逻辑 + if (this.curCardType === CardType.Potion) { + if (this.purchasedSlots[_index]) { + oops.gui.toast("该物品已购买"); + return; + } + + if (smc.vmdata.gold < selectedData.price) { + oops.gui.toast("金币不足"); + return; + } + + // 扣除金币 + smc.updateGold(-selectedData.price); + + // 发送使用物品事件 + oops.message.dispatchEvent(GameEvent.UseItemCard, selectedData.id); + + // 标记已购买 + this.purchasedSlots[_index] = true; + + // 视觉反馈 (变灰) + const sprite = selectedCardNode.getComponent(Sprite); + if (sprite) sprite.color = new Color(150, 150, 150); + + oops.gui.toast("购买成功"); + + // 检查是否所有卡片都已购买,如果是则关闭 + let allPurchased = true; + // 检查当前显示的卡片是否都买了 + if (this.card1.active && !this.purchasedSlots[1]) allPurchased = false; + if (this.card2.active && !this.purchasedSlots[2]) allPurchased = false; + if (this.card3.active && !this.purchasedSlots[3]) allPurchased = false; + if (this.card4.active && !this.purchasedSlots[4]) allPurchased = false; + + if (allPurchased) { + this.node.active = false; + } + return; + } + this.hasSelected = true; console.log("选择卡片:", selectedData.name, "类型:", this.curCardType); @@ -216,6 +279,13 @@ export class MissionCardComp extends CCComp { } } + /** + * 关闭界面 + */ + close() { + this.node.active = false; + } + /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ reset() { this.node.destroy();