2 Commits

Author SHA1 Message Date
walkpan
3b93ffdd7e refactor(game): 将玩家收集数据移出vmdata以优化结构
将 collection 对象从 vmdata 中移出,作为 SingletonModuleComp 的直接属性。这消除了不必要的嵌套层级,使数据访问更直接,并提高了代码可读性。同时更新了 TalentsComp 中所有相关引用,确保功能一致性。
2026-04-28 08:48:23 +08:00
walkpan
c48e529392 feat(talent): 重构天赋系统配置并添加图标显示
- 将天赋配置从 TalentsComp.ts 提取到独立的 TalentSet.ts 文件
- 为每个天赋添加图标支持,在天赋名称前显示对应图标
- 改进天赋描述,使用动态数值替换模板中的 {value} 占位符
- 更新天赋项预制件以支持新的配置结构
- 修改 UI 图片资源并调整预制件的视觉样式
2026-04-27 23:41:58 +08:00
8 changed files with 2639 additions and 1383 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -55,10 +55,25 @@ export class SingletonModuleComp extends ecs.Comp {
noStop:false, noStop:false,
showInfo:true, showInfo:true,
} }
guides:any=[0,0,0,0,0] guides:any=[0,0,0,0,0]
current_guide:number=0 current_guide:number=0
fight_hero: number = 5001; // 单个出战英雄 fight_hero: number = 5001; // 单个出战英雄
heros:any= [5001] heros:any= [5001]
collection: {
talents: Record<number, number>;
player_level: number;
player_exp: number;
talent_points: number;
} = {
talents: {}, // 存储各个天赋的等级: { talent_id: level }
player_level: 1, // 玩家等级
player_exp: 0, // 玩家当前经验
talent_points: 0, // 当前可用天赋点
};
vmdata: any = { vmdata: any = {
game_over:false, game_over:false,
game_pause:false, game_pause:false,
@@ -129,13 +144,6 @@ export class SingletonModuleComp extends ecs.Comp {
} as GameScoreStats, } as GameScoreStats,
gold: 0, // 金币数据MVVM绑定字段 gold: 0, // 金币数据MVVM绑定字段
collection: {
talents: {}, // 存储各个天赋的等级: { talent_id: level }
player_level: 1, // 玩家等级
player_exp: 0, // 玩家当前经验
talent_points: 0, // 当前可用天赋点
},
}; };
@@ -258,7 +266,7 @@ export class SingletonModuleComp extends ecs.Comp {
if(CloudData.data.fight_hero) this.fight_hero=CloudData.data.fight_hero if(CloudData.data.fight_hero) this.fight_hero=CloudData.data.fight_hero
// 恢复收集记录 // 恢复收集记录
if(CloudData.data.collection) { if(CloudData.data.collection) {
this.vmdata.collection = CloudData.data.collection; this.collection = CloudData.data.collection;
} }
} }
@@ -271,7 +279,7 @@ export class SingletonModuleComp extends ecs.Comp {
gold:this.vmdata.gold, gold:this.vmdata.gold,
heros:this.heros, heros:this.heros,
fight_hero:this.fight_hero, fight_hero:this.fight_hero,
collection: this.vmdata.collection collection: this.collection
} }
} }
addHero(hero_uuid:number){ addHero(hero_uuid:number){

View File

@@ -0,0 +1,107 @@
/**
* @file TalentSet.ts
* @description 天赋系统配置数据,包含经验要求、消耗、每个天赋的具体加成数值和描述。
*/
export interface TalentInfo {
/** 天赋 ID */
id: number;
/** 天赋名称 */
name: string;
/** 天赋图标或标识(可选) */
icon?: string;
/** 描述模板,使用 {value} 替换具体数值 */
desc: string;
/** 最大等级 */
maxLevel: number;
/** 每级提升的数值 */
valuePerLevel: number;
/** 获取指定等级下的实际加成数值 */
getValue: (level: number) => number;
}
export const TalentConfig = {
// 玩家升级所需经验配置
expRequirements: [
{ maxLevel: 10, expPerLevel: 100 },
{ maxLevel: 20, expPerLevel: 150 },
{ maxLevel: 30, expPerLevel: 200 }
],
// 天赋升级消耗点数 (第1级到第5级消耗)
costPerLevel: [1, 1, 2, 2, 3],
// 天赋列表
talents: [
{
id: 1, name: "攻击强化", icon: "⚔️",
desc: "所有英雄 ATK +{value}%",
maxLevel: 5,
valuePerLevel: 3,
getValue: (level: number) => level * 3
},
{
id: 2, name: "生命强化", icon: "❤️",
desc: "所有英雄 HP +{value}%",
maxLevel: 5,
valuePerLevel: 5,
getValue: (level: number) => level * 5
},
{
id: 3, name: "暴击强化", icon: "🔥",
desc: "所有英雄暴击率 +{value}%",
maxLevel: 5,
valuePerLevel: 2,
getValue: (level: number) => level * 2
},
{
id: 4, name: "风怒强化", icon: "⚡",
desc: "所有英雄风怒率 +{value}%",
maxLevel: 5,
valuePerLevel: 2,
getValue: (level: number) => level * 2
},
{
id: 5, name: "冰冻强化", icon: "❄️",
desc: "所有英雄冰冻率 +{value}%",
maxLevel: 5,
valuePerLevel: 2,
getValue: (level: number) => level * 2
},
{
id: 6, name: "穿刺强化", icon: "🗡️",
desc: "所有英雄穿刺 +{value}",
maxLevel: 5,
valuePerLevel: 0.2,
getValue: (level: number) => Number((level * 0.2).toFixed(1))
},
{
id: 7, name: "护盾强化", icon: "🛡️",
desc: "所有护盾效果 +{value}%",
maxLevel: 5,
valuePerLevel: 5,
getValue: (level: number) => level * 5
},
{
id: 8, name: "采购优惠", icon: "🛒",
desc: "购买英雄 -{value}金",
maxLevel: 5,
valuePerLevel: 1,
getValue: (level: number) => level * 1
},
{
id: 9, name: "刷新优惠", icon: "🔄",
desc: "刷新重抽 -{value}金",
maxLevel: 5,
valuePerLevel: 0.5,
getValue: (level: number) => Number((level * 0.5).toFixed(1))
},
{
id: 10, name: "出售补贴", icon: "💰",
desc: "出售英雄返还 +{value}%金币",
maxLevel: 5,
valuePerLevel: 10,
getValue: (level: number) => level * 10
}
] as TalentInfo[]
};

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "76a850b1-5eda-481f-a6e1-8e12e41db6c8",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -24,37 +24,10 @@ import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/modu
import { mLogger } from "../common/Logger"; import { mLogger } from "../common/Logger";
import { smc } from "../common/SingletonModuleComp"; import { smc } from "../common/SingletonModuleComp";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { TalentConfig, TalentInfo } from "../common/config/TalentSet";
const { ccclass, property } = _decorator; const { ccclass, property } = _decorator;
/**
* 天赋系统配置数据
*/
export const TalentConfig = {
// 升级所需经验配置
expRequirements: [
{ maxLevel: 10, expPerLevel: 100 },
{ maxLevel: 20, expPerLevel: 150 },
{ maxLevel: 30, expPerLevel: 200 }
],
// 天赋升级消耗点数
costPerLevel: [1, 1, 2, 2, 3], // 第1到第5级消耗
// 天赋列表
talents: [
{ id: 1, name: "攻击强化", desc: "所有英雄 ATK +3%", maxLevel: 5 },
{ id: 2, name: "生命强化", desc: "所有英雄 HP +5%", maxLevel: 5 },
{ id: 3, name: "暴击强化", desc: "所有英雄暴击率 +2%", maxLevel: 5 },
{ id: 4, name: "风怒强化", desc: "所有英雄风怒率 +2%", maxLevel: 5 },
{ id: 5, name: "冰冻强化", desc: "所有英雄冰冻率 +2%", maxLevel: 5 },
{ id: 6, name: "穿刺强化", desc: "所有英雄穿刺 +0.2", maxLevel: 5 },
{ id: 7, name: "护盾强化", desc: "所有护盾效果 +5%", maxLevel: 5 },
{ id: 8, name: "采购优惠", desc: "购买英雄 -1金", maxLevel: 5 },
{ id: 9, name: "刷新优惠", desc: "刷新重抽 -0.5金", maxLevel: 5 },
{ id: 10, name: "出售补贴", desc: "出售英雄返还 +10%金币", maxLevel: 5 }
]
};
/** /**
* TalentsComp —— 天赋系统界面组件 * TalentsComp —— 天赋系统界面组件
* *
@@ -125,7 +98,7 @@ export class TalentsComp extends CCComp {
/** 更新玩家等级、经验、天赋点信息 */ /** 更新玩家等级、经验、天赋点信息 */
private updatePlayerInfo() { private updatePlayerInfo() {
const collection = smc.vmdata.collection; const collection = smc.collection;
let level = collection.player_level || 1; let level = collection.player_level || 1;
let exp = collection.player_exp || 0; let exp = collection.player_exp || 0;
let points = collection.talent_points || 0; let points = collection.talent_points || 0;
@@ -164,7 +137,7 @@ export class TalentsComp extends CCComp {
private updateTalentList() { private updateTalentList() {
if (!this.talents_content || !this.prefab_talent_item) return; if (!this.talents_content || !this.prefab_talent_item) return;
const collection = smc.vmdata.collection; const collection = smc.collection;
if (!collection.talents) collection.talents = {}; if (!collection.talents) collection.talents = {};
// 如果内容为空,则实例化预制体 // 如果内容为空,则实例化预制体
@@ -186,7 +159,7 @@ export class TalentsComp extends CCComp {
} }
/** 更新单个天赋项的显示 */ /** 更新单个天赋项的显示 */
private updateTalentItem(itemNode: Node, talentInfo: any, currentLevel: number) { private updateTalentItem(itemNode: Node, talentInfo: TalentInfo, currentLevel: number) {
let lblName = itemNode.getChildByName("lbl_name")?.getComponent(Label); let lblName = itemNode.getChildByName("lbl_name")?.getComponent(Label);
let lblDesc = itemNode.getChildByName("lbl_desc")?.getComponent(Label); let lblDesc = itemNode.getChildByName("lbl_desc")?.getComponent(Label);
let lblLevel = itemNode.getChildByName("lbl_level")?.getComponent(Label); let lblLevel = itemNode.getChildByName("lbl_level")?.getComponent(Label);
@@ -194,13 +167,20 @@ export class TalentsComp extends CCComp {
let btnUpgradeNode = itemNode.getChildByName("btn_upgrade"); let btnUpgradeNode = itemNode.getChildByName("btn_upgrade");
let btnUpgrade = btnUpgradeNode?.getComponent(Button); let btnUpgrade = btnUpgradeNode?.getComponent(Button);
if (lblName) lblName.string = talentInfo.name; if (lblName) {
if (lblDesc) lblDesc.string = talentInfo.desc; lblName.string = (talentInfo.icon ? `${talentInfo.icon} ` : '') + talentInfo.name;
}
if (lblDesc) {
let currentVal = talentInfo.getValue(currentLevel);
lblDesc.string = talentInfo.desc.replace('{value}', currentVal.toString());
}
if (lblLevel) lblLevel.string = `Lv.${currentLevel}`; if (lblLevel) lblLevel.string = `Lv.${currentLevel}`;
let isMax = currentLevel >= talentInfo.maxLevel; let isMax = currentLevel >= talentInfo.maxLevel;
let cost = isMax ? 0 : TalentConfig.costPerLevel[currentLevel]; let cost = isMax ? 0 : TalentConfig.costPerLevel[currentLevel];
let points = smc.vmdata.collection.talent_points || 0; let points = smc.collection.talent_points || 0;
if (lblCost) { if (lblCost) {
lblCost.string = isMax ? "已满级" : `消耗: ${cost}`; lblCost.string = isMax ? "已满级" : `消耗: ${cost}`;
@@ -218,7 +198,7 @@ export class TalentsComp extends CCComp {
/** 点击升级按钮 */ /** 点击升级按钮 */
private onUpgradeClicked(talentId: number, currentLevel: number, cost: number) { private onUpgradeClicked(talentId: number, currentLevel: number, cost: number) {
const collection = smc.vmdata.collection; const collection = smc.collection;
let points = collection.talent_points || 0; let points = collection.talent_points || 0;
if (points >= cost && currentLevel < 5) { if (points >= cost && currentLevel < 5) {
@@ -244,7 +224,7 @@ export class TalentsComp extends CCComp {
// 看广告回调(预留) // 看广告回调(预留)
this.watch_ad().then(success => { this.watch_ad().then(success => {
if (success) { if (success) {
const collection = smc.vmdata.collection; const collection = smc.collection;
// 计算已消耗的天赋点总和 // 计算已消耗的天赋点总和
let refundedPoints = 0; let refundedPoints = 0;
for (let id in collection.talents) { for (let id in collection.talents) {