feat(物品系统): 添加物品使用功能及相关配置
- 在GameEvent枚举中添加UseItemCard事件 - 创建ItemSet物品配置表,包含8种不同效果的物品 - 在HeroAttrsComp中添加物品使用逻辑,处理物品效果应用 - 修改MissionCardComp支持物品购买界面和购买逻辑 - 添加物品购买后的视觉反馈和状态管理
This commit is contained in:
@@ -48,6 +48,7 @@ export enum GameEvent {
|
|||||||
FuncSelect = "FuncSelect",
|
FuncSelect = "FuncSelect",
|
||||||
TalentSelect = "TalentSelect",
|
TalentSelect = "TalentSelect",
|
||||||
UseTalentCard = "UseTalentCard",
|
UseTalentCard = "UseTalentCard",
|
||||||
|
UseItemCard = "UseItemCard",
|
||||||
NewWave = "NewWave",
|
NewWave = "NewWave",
|
||||||
AD_BACK_TRUE = "AD_BACK_TRUE",
|
AD_BACK_TRUE = "AD_BACK_TRUE",
|
||||||
AD_BACK_FALSE = "AD_BACK_FALSE",
|
AD_BACK_FALSE = "AD_BACK_FALSE",
|
||||||
|
|||||||
@@ -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<number, ItemConf> = {
|
||||||
|
// ==================== 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
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { BuffConf } from "../common/config/SkillSet";
|
|||||||
import { HeroInfo, AttrSet } from "../common/config/heroSet";
|
import { HeroInfo, AttrSet } from "../common/config/heroSet";
|
||||||
import { HeroSkillsComp } from "./HeroSkills";
|
import { HeroSkillsComp } from "./HeroSkills";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
|
import { ItemSet } from "../common/config/ItemSet";
|
||||||
|
|
||||||
|
|
||||||
interface talTrigger{
|
interface talTrigger{
|
||||||
@@ -78,10 +79,17 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
onLoad() {
|
onLoad() {
|
||||||
// 监听升级事件
|
// 监听升级事件
|
||||||
oops.message.on(GameEvent.CanUpdateLv, this.onLevelUp, this);
|
oops.message.on(GameEvent.CanUpdateLv, this.onLevelUp, this);
|
||||||
|
oops.message.on(GameEvent.UseItemCard, this.onUseItemCard, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy() {
|
onDestroy() {
|
||||||
oops.message.off(GameEvent.CanUpdateLv, this.onLevelUp, this);
|
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) {
|
useValueTalByUuid(t_uuid: number) {
|
||||||
const buff = this.BUFFS_TAL[t_uuid];
|
const buff = this.BUFFS_TAL[t_uuid];
|
||||||
if (!buff) return;
|
if (!buff) return;
|
||||||
const attrIndex = buff.attrIndex;
|
buff.count--;
|
||||||
delete this.BUFFS_TAL[t_uuid];
|
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);
|
this.recalculateSingleAttr(attrIndex);
|
||||||
|
|
||||||
|
oops.gui.toast(`使用了 ${item.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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 { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { talConf, ItalConf } from "../common/config/TalSet";
|
import { talConf, ItalConf } from "../common/config/TalSet";
|
||||||
|
import { ItemSet } from "../common/config/ItemSet";
|
||||||
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
|
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
@@ -35,12 +37,17 @@ export class MissionCardComp extends CCComp {
|
|||||||
// 当前卡片类型
|
// 当前卡片类型
|
||||||
curCardType: CardType = CardType.Talent;
|
curCardType: CardType = CardType.Talent;
|
||||||
|
|
||||||
|
// 已购买的卡片槽位标记 (用于物品购买)
|
||||||
|
purchasedSlots: boolean[] = [false, false, false, false, false];
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
oops.message.on(GameEvent.TalentSelect, this.onTalentSelect, this);
|
oops.message.on(GameEvent.TalentSelect, this.onTalentSelect, this);
|
||||||
|
oops.message.on(GameEvent.ShopOpen, this.onShopOpen, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy() {
|
onDestroy() {
|
||||||
oops.message.off(GameEvent.TalentSelect, this.onTalentSelect, this);
|
oops.message.off(GameEvent.TalentSelect, this.onTalentSelect, this);
|
||||||
|
oops.message.off(GameEvent.ShopOpen, this.onShopOpen, this);
|
||||||
this.ent.destroy();
|
this.ent.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,13 +63,28 @@ export class MissionCardComp extends CCComp {
|
|||||||
if (card) {
|
if (card) {
|
||||||
const selected = card.getChildByName("selected");
|
const selected = card.getChildByName("selected");
|
||||||
if (selected) selected.active = false;
|
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 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) {
|
private onTalentSelect(event: string, args: any) {
|
||||||
this.node.active = true;
|
this.node.active = true;
|
||||||
this.hasSelected = false; // 重置选择状态
|
this.hasSelected = false; // 重置选择状态
|
||||||
@@ -180,6 +202,47 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (selectedData && selectedCardNode) {
|
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;
|
this.hasSelected = true;
|
||||||
console.log("选择卡片:", selectedData.name, "类型:", this.curCardType);
|
console.log("选择卡片:", selectedData.name, "类型:", this.curCardType);
|
||||||
|
|
||||||
@@ -216,6 +279,13 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭界面
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
this.node.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
||||||
reset() {
|
reset() {
|
||||||
this.node.destroy();
|
this.node.destroy();
|
||||||
|
|||||||
Reference in New Issue
Block a user