云环境和本地调试 添加

This commit is contained in:
2025-08-18 17:00:40 +08:00
parent addc61e2a9
commit a824d9a124
155 changed files with 6531 additions and 997 deletions

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "f680d91a-831f-4f99-b7ea-b45e3adff51a",

View File

@@ -0,0 +1,568 @@
import { WxCloudApi ,UserGameData} from "../wx_clound_client_api/WxCloudApi";
import { smc } from "./SingletonModuleComp";
/**
* 游戏数据同步管理器
* 负责管理fight_heros、heros、items、tals、equips的远程操作和本地同步
* 只有在远程修改成功后才同步修改本地数据
*/
export class GameDataSyncManager {
private static instance: GameDataSyncManager;
private constructor() {}
public static getInstance(): GameDataSyncManager {
if (!GameDataSyncManager.instance) {
GameDataSyncManager.instance = new GameDataSyncManager();
}
return GameDataSyncManager.instance;
}
/**
* 用远程数据覆盖本地数据(统一方法)
* @param remoteData 远程数据(云端或本地调试)
* @param dataSource 数据源描述
*/
async overrideLocalDataWithRemote(remoteData: UserGameData, dataSource: string) {
try {
console.log(`[Initialize]: 开始用${dataSource}数据覆盖客户端数据...`);
// 直接覆盖基础游戏数据
if (remoteData.data) {
Object.assign(smc.data, remoteData.data);
console.log(`[Initialize]: 基础游戏数据已从${dataSource}覆盖`);
}
// 直接覆盖出战英雄配置
if (remoteData.fight_heros) {
Object.assign(smc.fight_heros, remoteData.fight_heros);
console.log(`[Initialize]: 出战英雄配置已从${dataSource}覆盖`);
}
// 直接覆盖英雄数据
if (remoteData.heros) {
smc.heros = { ...remoteData.heros };
console.log(`[Initialize]: 英雄数据已从${dataSource}覆盖`);
}
// 直接覆盖道具数据
if (remoteData.items) {
Object.assign(smc.itmes, remoteData.items);
console.log(`[Initialize]: 道具数据已从${dataSource}覆盖`);
}
// 直接覆盖天赋数据
if (remoteData.tals) {
Object.assign(smc.tals, remoteData.tals);
console.log(`[Initialize]: 天赋数据已从${dataSource}覆盖`);
}
// 直接覆盖装备数据
if (remoteData.equips) {
Object.assign(smc.equips, remoteData.equips);
console.log(`[Initialize]: 装备数据已从${dataSource}覆盖`);
}
// 同步ViewModel数据
smc.syncData();
// 保存到本地存储(确保数据持久化)
// smc.saveGameData();
console.log(`[Initialize]: ${dataSource}数据覆盖完成,已保存到本地`);
} catch (error) {
console.error(`[Initialize]: ${dataSource}数据覆盖失败:`, error);
}
}
/**
* 批量更新出战英雄配置
* @param fightHeros 出战英雄配置对象
* @returns 是否成功
*/
async updateFightHeros(fightHeros: any): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 批量更新出战英雄配置:`, fightHeros);
const result = await WxCloudApi.updateFightHeros(fightHeros);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
Object.assign(smc.fight_heros, fightHeros);
console.log(`[GameDataSyncManager]: 出战英雄配置更新成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 出战英雄配置更新失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 更新出战英雄配置异常:`, error);
return false;
}
}
/**
* 重置出战英雄配置为默认值
* @returns 是否成功
*/
async resetFightHeros(): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 重置出战英雄配置`);
const result = await WxCloudApi.resetFightHeros();
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
smc.fight_heros = result.result.data;
console.log(`[GameDataSyncManager]: 出战英雄配置重置成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 出战英雄配置重置失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 重置出战英雄配置异常:`, error);
return false;
}
}
// ==================== 英雄管理 ====================
/**
* 添加新英雄到用户库存
* @param heroId 英雄ID
* @param heroData 英雄数据(可选)
* @returns 是否成功
*/
async addHero(heroId: number, heroData?: any): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 添加英雄 ID:${heroId}, 数据:`, heroData);
const result = await WxCloudApi.addHero(heroId, heroData);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
smc.heros[heroId] = result.result.data;
console.log(`[GameDataSyncManager]: 英雄添加成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 英雄添加失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 添加英雄异常:`, error);
return false;
}
}
/**
* 更新英雄的多个属性
* @param heroId 英雄ID
* @param updateData 要更新的属性
* @returns 是否成功
*/
async updateHero(heroId: number, updateData: any): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 更新英雄 ID:${heroId}, 更新数据:`, updateData);
const result = await WxCloudApi.updateHero(heroId, updateData);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
Object.assign(smc.heros[heroId], result.result.data.new_data);
console.log(`[GameDataSyncManager]: 英雄更新成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 英雄更新失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 更新英雄异常:`, error);
return false;
}
}
/**
* 设置英雄的单个属性值
* @param heroId 英雄ID
* @param property 属性名
* @param value 属性值
* @returns 是否成功
*/
async setHeroProperty(heroId: number, property: any, value: any): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 设置英雄属性 ID:${heroId}, 属性:${property}, 值:${value}`);
const result = await WxCloudApi.setHeroProperty(heroId, property, value);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
smc.heros[heroId][property] = value;
console.log(`[GameDataSyncManager]: 英雄属性设置成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 英雄属性设置失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 设置英雄属性异常:`, error);
return false;
}
}
/**
* 英雄升级指定级数
* @param heroId 英雄ID
* @param levels 升级级数默认1级
* @returns 是否成功
*/
async levelUpHero(heroId: number, exp:number,gold:number,levels: number = 1,): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 英雄升级 ID:${heroId}, 级数:${levels}`);
const result = await WxCloudApi.levelUpHero(heroId, exp,gold,levels);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
smc.heros[heroId].lv = result.result.data.new_value;
console.log(`[GameDataSyncManager]: 英雄升级成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 英雄升级失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 英雄升级异常:`, error);
return false;
}
}
/**
* 删除指定英雄
* @param heroId 英雄ID
* @returns 是否成功
*/
async deleteHero(heroId: number): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 删除英雄 ID:${heroId}`);
const result = await WxCloudApi.deleteHero(heroId);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
delete smc.heros[heroId];
console.log(`[GameDataSyncManager]: 英雄删除成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 英雄删除失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 删除英雄异常:`, error);
return false;
}
}
// ==================== 库存管理 (items, tals, equips) ====================
/**
* 增加指定物品的数量
* @param type 库存类型 ('items', 'tals', 'equips')
* @param itemId 物品ID
* @param count 添加数量
* @returns 是否成功
*/
async addInventoryItem(type: 'items' | 'tals' | 'equips', itemId: number, count: number): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 增加库存物品 类型:${type}, ID:${itemId}, 数量:${count}`);
const result = await WxCloudApi.addInventoryItem(type, itemId, count);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
const targetData = this.getTargetData(type);
targetData[itemId] = (targetData[itemId] || 0) + count;
console.log(`[GameDataSyncManager]: 库存物品增加成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 库存物品增加失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 增加库存物品异常:`, error);
return false;
}
}
/**
* 消耗指定数量的物品
* @param type 库存类型 ('items', 'tals', 'equips')
* @param itemId 物品ID
* @param count 消耗数量
* @returns 是否成功
*/
async consumeInventoryItem(type: 'items' | 'tals' | 'equips', itemId: number, count: number): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 消耗库存物品 类型:${type}, ID:${itemId}, 数量:${count}`);
const result = await WxCloudApi.consumeInventoryItem(type, itemId, count);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
const targetData = this.getTargetData(type);
targetData[itemId] = Math.max(0, (targetData[itemId] || 0) - count);
console.log(`[GameDataSyncManager]: 库存物品消耗成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 库存物品消耗失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 消耗库存物品异常:`, error);
return false;
}
}
/**
* 直接设置物品的数量
* @param type 库存类型 ('items', 'tals', 'equips')
* @param itemId 物品ID
* @param count 新的数量
* @returns 是否成功
*/
async setInventoryItem(type: 'items' | 'tals' | 'equips', itemId: number, count: number): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 设置库存物品 类型:${type}, ID:${itemId}, 数量:${count}`);
const result = await WxCloudApi.setInventoryItem(type, itemId, count);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
const targetData = this.getTargetData(type);
targetData[itemId] = count;
console.log(`[GameDataSyncManager]: 库存物品设置成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 库存物品设置失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 设置库存物品异常:`, error);
return false;
}
}
/**
* 批量更新多个物品的数量
* @param type 库存类型 ('items', 'tals', 'equips')
* @param data 更新数据对象
* @param merge 是否合并更新默认true
* @returns 是否成功
*/
async updateInventory(type: 'items' | 'tals' | 'equips', data: any, merge: boolean = true): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 批量更新库存 类型:${type}, 数据:`, data);
const result = await WxCloudApi.updateInventory(type, data, merge);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
const targetData = this.getTargetData(type);
if (merge) {
Object.assign(targetData, data);
} else {
Object.keys(targetData).forEach(key => delete targetData[key]);
Object.assign(targetData, data);
}
console.log(`[GameDataSyncManager]: 库存批量更新成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 库存批量更新失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 批量更新库存异常:`, error);
return false;
}
}
/**
* 重置指定类型的库存为默认值
* @param type 库存类型 ('items', 'tals', 'equips')
* @returns 是否成功
*/
async resetInventory(type: 'items' | 'tals' | 'equips'): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 重置库存 类型:${type}`);
const result = await WxCloudApi.resetInventory(type);
if (result.result.code === 200) {
// 远程修改成功,同步本地数据
const targetData = this.getTargetData(type);
Object.keys(targetData).forEach(key => delete targetData[key]);
Object.assign(targetData, result.result.data);
console.log(`[GameDataSyncManager]: 库存重置成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 库存重置失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 重置库存异常:`, error);
return false;
}
}
// ==================== 便捷方法 ====================
/**
* 增加道具
* @param itemId 道具ID
* @param count 数量
* @returns 是否成功
*/
async addItem(itemId: number, count: number): Promise<boolean> {
return this.addInventoryItem('items', itemId, count);
}
/**
* 消耗道具
* @param itemId 道具ID
* @param count 数量
* @returns 是否成功
*/
async consumeItem(itemId: number, count: number): Promise<boolean> {
return this.consumeInventoryItem('items', itemId, count);
}
/**
* 增加天赋点
* @param talId 天赋ID
* @param count 数量
* @returns 是否成功
*/
async addTalent(talId: number, count: number): Promise<boolean> {
return this.addInventoryItem('tals', talId, count);
}
/**
* 消耗天赋点
* @param talId 天赋ID
* @param count 数量
* @returns 是否成功
*/
async consumeTalent(talId: number, count: number): Promise<boolean> {
return this.consumeInventoryItem('tals', talId, count);
}
/**
* 增加装备
* @param equipId 装备ID
* @param count 数量
* @returns 是否成功
*/
async addEquipment(equipId: number, count: number): Promise<boolean> {
return this.addInventoryItem('equips', equipId, count);
}
/**
* 消耗装备
* @param equipId 装备ID
* @param count 数量
* @returns 是否成功
*/
async consumeEquipment(equipId: number, count: number): Promise<boolean> {
return this.consumeInventoryItem('equips', equipId, count);
}
// ==================== 私有辅助方法 ====================
/**
* 根据类型获取对应的目标数据对象
* @param type 库存类型
* @returns 对应的数据对象
*/
private getTargetData(type: 'items' | 'tals' | 'equips'): any {
switch (type) {
case 'items':
return smc.itmes;
case 'tals':
return smc.tals;
case 'equips':
return smc.equips;
default:
throw new Error(`未知的库存类型: ${type}`);
}
}
/**
* 从云端加载所有游戏数据并同步到本地
* @returns 是否成功
*/
async loadAllGameData(): Promise<boolean> {
try {
console.log(`[GameDataSyncManager]: 从云端加载所有游戏数据`);
const result = await WxCloudApi.getAllGameData();
if (result.result.code === 200) {
// 远程数据获取成功,同步本地数据
const cloudData = result.result.data;
smc.data = cloudData.data;
smc.fight_heros = cloudData.fight_heros;
smc.heros = cloudData.heros;
smc.itmes = cloudData.items;
smc.tals = cloudData.tals;
smc.equips = cloudData.equips;
// 同步vmdata
smc.syncData();
console.log(`[GameDataSyncManager]: 云端数据加载成功,本地数据已同步`);
return true;
} else {
console.warn(`[GameDataSyncManager]: 云端数据加载失败: ${result.result.msg}`);
return false;
}
} catch (error) {
console.error(`[GameDataSyncManager]: 加载云端数据异常:`, error);
return false;
}
}
}
// 导出单例实例
export const gameDataSyncManager = GameDataSyncManager.getInstance();
/*
使用示例:
// 1. 出战英雄管理
await gameDataSyncManager.setFightHero(0, 5001); // 设置位置0的英雄
await gameDataSyncManager.swapFightHeros(0, 1); // 交换位置0和1的英雄
await gameDataSyncManager.updateFightHeros({0: 5001, 1: 5005}); // 批量更新
// 2. 英雄管理
await gameDataSyncManager.addHero(5008, {uuid: 5008, lv: 1}); // 添加新英雄
await gameDataSyncManager.levelUpHero(5001, 5); // 英雄升级5级
await gameDataSyncManager.setHeroProperty(5001, "exp", 1000); // 设置英雄经验
// 3. 库存管理
await gameDataSyncManager.addItem(1001, 10); // 增加道具
await gameDataSyncManager.consumeItem(1001, 2); // 消耗道具
await gameDataSyncManager.addTalent(2001, 5); // 增加天赋点
await gameDataSyncManager.addEquipment(3001, 2); // 增加装备
// 4. 数据加载
await gameDataSyncManager.loadAllGameData(); // 从云端加载所有数据
注意:所有方法都返回 Promise<boolean>true表示成功false表示失败
只有在远程修改成功后,本地数据才会被同步修改
*/

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "89c45a3b-d0bf-4e45-9e27-b7d714ba7e29",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -4,6 +4,10 @@ import { Initialize } from "../initialize/Initialize";
import { GameMap } from "../map/GameMap";
import { HeroUI, VmInfo } from "./config/Mission";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { WxCloudApi } from "../wx_clound_client_api/WxCloudApi";
import { gameDataSyncManager } from "./GameDataSyncManager";
import { GameSet } from "./config/BoxSet";
import { Test } from "./Test";
// import { Role } from "../role/Role";
@@ -15,6 +19,8 @@ export class SingletonModuleComp extends ecs.Comp {
initialize: Initialize = null!;
/** 游戏地图 */
map: GameMap = null!;
/** 游戏数据同步管理器 */
private gameDataSyncManager = gameDataSyncManager;
mission:any={
status:0, //0:未开始 1:进行中 2:胜利 3:失败
play:false,
@@ -37,21 +43,19 @@ export class SingletonModuleComp extends ecs.Comp {
ckey:0, //铜钥匙 解锁稀有英雄 也可以直接兑换金币
skey:0, //银钥匙 解锁史诗英雄 也可以直接兑换金币
gkey:0, //金钥匙 解锁传说英雄 也可以直接兑换金币
}
fight_heros:any={
0:5001,
1:5005,
2:0,
3:0,
4:0,
}
fight_heros:any={ 0:5001, 1:5005, 2:0, 3:0, 4:0, }
heros:any = {
5001:{uuid:5001,lv:1},
5005:{uuid:5005,lv:1},
5007:{uuid:5007,lv:1},
};
itmes:any={
}
tals:any={
}
equips:any={
}
monsters:any = [];
sk_info:any = []
monsters_dead:any = []
@@ -60,32 +64,46 @@ export class SingletonModuleComp extends ecs.Comp {
vmdata: any = {
game_over:false,
game_pause:false,
data:{
score:0,
mission:1,
gold:100, //升级主要资源
diamond:100, //商店购买 及 双倍奖励资源
meat:0,
exp:0, //升级经验
ghstone:0, //英雄石 绿色 普通英雄升星
bhstone:0, //英雄石 蓝色 稀有英雄升星
phlestone:0, //英雄石 紫色 史诗英雄升星
rhstone:0, //英雄石 红色 传说英雄升星
herocard:0, //英雄卡,抽卡凭证
ckey:0, //铜钥匙 解锁稀有英雄 也可以直接兑换金币
skey:0, //银钥匙 解锁史诗英雄 也可以直接兑换金币
gkey:0, //金钥匙 解锁传说英雄 也可以直接兑换金币
},
mission_data:{
gold:1000,//金币
exp:0,//经验
score:0,//分数
diamond:0,//钻石
mission:1,//关卡
chapter:1,//章节
level:1,//关卡等级
max_mission:4,//最大关卡
meat:0,//肉
mon_num:0,//怪物数量
hero_num:0,//英雄数量
wave_time_num:0,//波次时间
in_fight:false,
fight_time:0,//战斗时间
level:1,//关卡等级
max_mission:4,//最大关卡
},
reward:{
gold:0,
meat:0,
diamond:0,
score:0,
exp:0,
gcard:0,
bcard:0,
pcard:0,
ycard:0,
mission:0,
gold:0, //升级主要资源
diamond:0, //商店购买 及 双倍奖励资源
meat:0,
exp:0, //升级经验
ghstone:0, //英雄石 绿色 普通英雄升星
bhstone:0, //英雄石 蓝色 稀有英雄升星
phlestone:0, //英雄石 紫色 史诗英雄升星
rhstone:0, //英雄石 红色 传说英雄升星
herocard:0, //英雄卡,抽卡凭证
ckey:0, //铜钥匙 解锁稀有英雄 也可以直接兑换金币
skey:0, //银钥匙 解锁史诗英雄 也可以直接兑换金币
gkey:0, //金钥匙 解锁传说英雄 也可以直接兑换金币
}
};
vmAdd() {
@@ -97,483 +115,97 @@ export class SingletonModuleComp extends ecs.Comp {
}
}
// ==================== 本地存储管理方法 ====================
/**
* 初始化默认游戏数据
*/
initDefaultData() {
// 确保出战英雄有默认值
if (!this.fight_heros || Object.keys(this.fight_heros).length === 0) {
this.fight_heros = {
0: 5001,
1: 5005,
2: 0,
3: 0,
4: 0,
};
}
// 确保英雄属性有默认值
if (!this.heros || Object.keys(this.heros).length === 0) {
this.heros = {
5001: {lv: 1},
5005: {lv: 1},
5007: {lv: 1},
};
}
// 确保游戏数据有默认值
if (!this.data || Object.keys(this.data).length === 0) {
this.data = {
score: 888,
mission: 1,
gold: 100,
diamond: 100,
};
}
console.log("[SMC]: 默认数据已初始化 - 出战英雄:", this.fight_heros, "英雄属性:", this.heros, "游戏数据:", this.data);
}
/**
* 保存游戏数据到本地存储
*/
saveGameData() {
try {
// 保存出战英雄数据
const fightHerosJson = JSON.stringify(this.fight_heros);
oops.storage.set("fight_heros", fightHerosJson);
// 保存英雄属性数据
const herosJson = JSON.stringify(this.heros);
oops.storage.set("heros", herosJson);
// 保存游戏数据(金币、钻石等)
const dataJson = JSON.stringify(this.data);
oops.storage.set("game_data", dataJson);
console.log("[SMC]: 游戏数据已保存 - 出战英雄:", this.fight_heros, "英雄属性:", this.heros, "游戏数据:", this.data);
return true;
} catch (error) {
console.error("[SMC]: 保存游戏数据失败:", error);
return false;
}
}
/**
* 保存英雄数据到本地存储(兼容旧方法名)
*/
saveHeroData() {
return this.saveGameData();
}
/**
* 从本地存储加载游戏数据
*/
loadGameData() {
console.log("[SMC]: 加载游戏数据")
try {
let hasAnyData = false;
// 加载出战英雄数据
const savedFightHeros = oops.storage.get("fight_heros");
if (savedFightHeros && savedFightHeros !== "") {
const fightHerosData = JSON.parse(savedFightHeros);
this.fight_heros = fightHerosData;
console.log("[SMC]: 从本地加载出战英雄数据:", fightHerosData);
hasAnyData = true;
} else {
console.log("[SMC]: 未找到本地出战英雄数据,使用默认配置");
}
// 加载英雄属性数据
const savedHeros = oops.storage.get("heros");
if (savedHeros && savedHeros !== "") {
const herosData = JSON.parse(savedHeros);
this.heros = herosData;
console.log("[SMC]: 从本地加载英雄属性数据:", herosData);
hasAnyData = true;
} else {
console.log("[SMC]: 未找到本地英雄属性数据,使用默认配置");
}
// 加载游戏数据
const savedData = oops.storage.get("game_data");
if (savedData && savedData !== "") {
const gameData = JSON.parse(savedData);
this.data = gameData;
console.log("[SMC]: 从本地加载游戏数据:", gameData);
hasAnyData = true;
} else {
console.log("[SMC]: 未找到本地游戏数据,使用默认配置");
}
// 如果没有任何本地数据,说明是首次启动,初始化并保存默认数据
if (!hasAnyData) {
console.log("[SMC]: 首次启动,初始化默认游戏数据");
this.initDefaultData();
this.saveGameData();
return true; // 首次启动也算成功
}
return hasAnyData;
} catch (error) {
console.error("[SMC]: 加载游戏数据失败:", error);
return false;
}
}
/**
* 从本地存储加载英雄数据(兼容旧方法名)
*/
loadHeroData() {
return this.loadGameData();
}
/**
* 设置出战英雄
* @param position 出战位置 (0-4)
* @param heroId 英雄ID0表示移除
* @param autoSave 是否自动保存 (默认true)
*/
setFightHero(position: number, heroId: number, autoSave: boolean = true) {
if (position < 0 || position > 4) {
console.warn("[SMC]: 出战位置无效:", position);
return false;
}
this.fight_heros[position] = heroId;
console.log(`[SMC]: 设置出战位置${position} -> 英雄${heroId}`);
if (autoSave) {
this.saveGameData();
}
return true;
}
/**
* 获取出战英雄ID
* @param position 出战位置 (0-4)
*/
getFightHero(position: number): number {
if (position < 0 || position > 4) {
console.warn("[SMC]: 出战位置无效:", position);
return 0;
}
return this.fight_heros[position] || 0;
}
/**
* 获取当前出战英雄列表(不包含空位)
*/
getActiveFightHeros(): number[] {
const activeHeros: number[] = [];
for (let i = 0; i < 5; i++) {
const heroId = this.fight_heros[i];
if (heroId && heroId > 0) {
activeHeros.push(heroId);
}
}
return activeHeros;
}
/**
* 设置英雄属性
* @param heroId 英雄ID
* @param property 属性名 (如: lv, exp等)
* @param value 属性值
* @param autoSave 是否自动保存 (默认true)
*/
setHeroProperty(heroId: number, property: string, value: any, autoSave: boolean = true) {
if (!this.heros[heroId]) {
this.heros[heroId] = {};
}
this.heros[heroId][property] = value;
console.log(`[SMC]: 设置英雄${heroId}${property} = ${value}`);
if (autoSave) {
this.saveGameData();
}
}
/**
* 获取英雄属性
* @param heroId 英雄ID
* @param property 属性名
* @param defaultValue 默认值
*/
getHeroProperty(heroId: number, property: string, defaultValue: any = null): any {
if (!this.heros[heroId]) {
return defaultValue;
}
return this.heros[heroId][property] !== undefined ? this.heros[heroId][property] : defaultValue;
}
/**
* 英雄升级
* @param heroId 英雄ID
* @param levels 升级级数 (默认1级)
* @param autoSave 是否自动保存 (默认true)
*/
levelUpHero(heroId: number, levels: number = 1, autoSave: boolean = true) {
const currentLevel = this.getHeroProperty(heroId, "lv", 1);
const newLevel = currentLevel + levels;
this.setHeroProperty(heroId, "lv", newLevel, autoSave);
console.log(`[SMC]: 英雄${heroId}升级: ${currentLevel} -> ${newLevel}`);
}
getHasHeroUUID() {
return Object.keys(this.heros).map(Number)
}
/**
* 获取英雄等级
* @param heroId 英雄ID
*/
getHeroLevel(heroId: number): number {
return this.getHeroProperty(heroId, "lv", 1);
}
/**
* 清除所有本地存储数据
*/
clearAllSaveData() {
try {
oops.storage.remove("fight_heros");
oops.storage.remove("heros");
oops.storage.remove("game_data");
console.log("[SMC]: 已清除所有本地存储数据");
return true;
} catch (error) {
console.error("[SMC]: 清除存储数据失败:", error);
return false;
}
}
/**
* 重置英雄数据为默认值
* @param autoSave 是否自动保存 (默认true)
*/
resetHeroData(autoSave: boolean = true) {
// 重置为默认出战英雄
this.fight_heros = {
0: 5001,
1: 5005,
2: 0,
3: 0,
4: 0,
};
// 重置为默认英雄属性
this.heros = {
5001: {lv: 1},
5005: {lv: 1},
5007: {lv: 1},
};
console.log("[SMC]: 英雄数据已重置为默认值");
if (autoSave) {
this.saveGameData();
}
}
// ==================== 游戏数据管理方法 ====================
/**
* 设置游戏数据属性
* @param property 属性名 (如: score, mission, gold, diamond)
* @param value 属性值
* @param autoSave 是否自动保存 (默认true)
*/
setGameProperty(property: string, value: any, autoSave: boolean = true) {
this.data[property] = value;
this.vmdata.mission_data[property] = value;
console.log(`[SMC]: 设置游戏数据 ${property} = ${value}`);
if (autoSave) {
this.saveGameData();
}
}
addGameProperty(property: string, value: any, autoSave: boolean = true) {
this.data[property] = this.data[property] + value;
this.vmdata.mission_data[property] = this.data[property]
console.log(`[SMC]:增加游戏数据 ${property} = ${value}`);
if (autoSave) {
this.saveGameData();
}
}
spendGameProperty(property: string, value: any, autoSave: boolean = true) {
this.data[property] = this.data[property] - value;
this.vmdata.mission_data[property] = this.data[property]
console.log(`[SMC]: 消耗游戏数据 ${property} = ${value}`);
if (autoSave) {
this.saveGameData();
}
}
/**
* 获取游戏数据属性
* @param property 属性名
* @param defaultValue 默认值
*/
getGameProperty(property: string, defaultValue: any = null): any {
return this.data[property] !== undefined ? this.data[property] : defaultValue;
}
syncData(){
this.vmdata.mission_data.gold=this.getGameProperty("gold", 0)
this.vmdata.mission_data.meat=this.getGameProperty("meat", 0)
this.vmdata.mission_data.diamond=this.getGameProperty("diamond", 0)
this.vmdata.mission_data.mission=this.getGameProperty("mission", 1)
this.vmdata.mission_data.score=this.getGameProperty("score", 0)
this.vmdata.mission_data.exp=this.getGameProperty("exp", 0)
// // 计算章节和关卡等级
// const currentMission = this.getGameProperty("mission", 1)
// this.vmdata.mission_data.chapter = Math.floor((currentMission - 1) / 10) + 1
// this.vmdata.mission_data.level = ((currentMission - 1) % 10) + 1
}
initReward(){
this.vmdata.reward.gold=0
this.vmdata.reward.meat=0
this.vmdata.reward.diamond=0
this.vmdata.reward.score=0
this.vmdata.reward.exp=0
this.vmdata.reward.gcard=0
this.vmdata.reward.bcard=0
this.vmdata.reward.pcard=0
this.vmdata.reward.ycard=0
}
/**
* 增加金币
* @param amount 金币数量
* @param autoSave 是否自动保存 (默认true)
*/
addGold(amount: number, autoSave: boolean = true) {
const currentGold = this.getGameProperty("gold", 0);
const newGold = Math.max(0, currentGold + amount);
this.setGameProperty("gold", newGold, autoSave);
console.log(`[SMC]: 金币变更: ${currentGold} -> ${newGold} (${amount > 0 ? '+' : ''}${amount})`);
return newGold;
}
// ==================== 数据管理方法 ====================
/**
* 消耗金币
* @param amount 消耗数量
* 同步数据到vmdata
*/
syncData(){
this.vmdata.data = this.data;
}
/**
* 判断是否为微信客户端
*/
private isWxClient(): boolean {
// 检查是否存在微信API
return typeof wx !== 'undefined' && typeof (wx as any).getSystemInfoSync === 'function';
}
//调试用
syncDataFromLocal(){
if(this.isWxClient()) return
const loginResult = new Test().load_data_from_local()
this.gameDataSyncManager.overrideLocalDataWithRemote(loginResult, "本地调试");
}
setFightHero(position:number,heroId:number,autoSave:boolean=true){
this.fight_heros[position] = heroId;
if(autoSave){
this.updateFightHeros()
}
}
updateFightHeros(){
this.gameDataSyncManager.updateFightHeros(this.fight_heros);
}
resetFightHeros(){
this.gameDataSyncManager.resetFightHeros();
}
getHasHeroUUID(){
let heros=this.heros
let heros_uuid=[]
for(let key in heros){
heros_uuid.push(heros[key].uuid)
}
return heros_uuid
}
levelUpHero(heroId:number,exp:number,gold:number){
let result=this.gameDataSyncManager.levelUpHero(heroId,exp,gold);
if(result){
this.heros[heroId].lv++;
}
return result;
}
// ==================== 统一的数据操作接口 ====================
/**
* 增加游戏数据属性(统一接口)
* @param property 属性名
* @param value 增加的值
* @param autoSave 是否自动保存 (默认true)
* @returns 操作结果
*/
async addGameProperty(property: string, value: any, autoSave: boolean = true): Promise<any> {
const currentValue = this.data[property] || 0;
const newValue = currentValue + value;
this.data[property] = newValue;
this.vmdata.data[property] = newValue;
console.log(`[SMC]: 增加游戏数据 ${property} = ${value}, 当前值: ${newValue}`);
return newValue;
}
/**
* 消耗游戏数据属性(统一接口)
* @param property 属性名
* @param value 消耗的值
* @param autoSave 是否自动保存 (默认true)
* @returns 是否成功消耗
*/
spendGold(amount: number, autoSave: boolean = true): boolean {
const currentGold = this.getGameProperty("gold", 0);
if (currentGold < amount) {
console.warn(`[SMC]: 金币不足,当前: ${currentGold}, 需要: ${amount}`);
async spendGameProperty(property: string, value: any, autoSave: boolean = true): Promise<boolean> {
const currentValue = this.data[property] || 0;
if (currentValue < value) {
console.warn(`[SMC]: ${property} 不足,当前: ${currentValue}, 需要: ${value}`);
return false;
}
this.addGold(-amount, autoSave);
const newValue = currentValue - value;
this.data[property] = newValue;
this.vmdata.data[property] = newValue;
console.log(`[SMC]: 消耗游戏数据 ${property} = ${value}, 当前值: ${newValue}`);
return true;
}
/**
* 增加钻石
* @param amount 钻石数量
* @param autoSave 是否自动保存 (默认true)
*/
addDiamond(amount: number, autoSave: boolean = true) {
const currentDiamond = this.getGameProperty("diamond", 0);
const newDiamond = Math.max(0, currentDiamond + amount);
this.setGameProperty("diamond", newDiamond, autoSave);
console.log(`[SMC]: 钻石变更: ${currentDiamond} -> ${newDiamond} (${amount > 0 ? '+' : ''}${amount})`);
return newDiamond;
}
/**
* 消耗钻石
* @param amount 消耗数量
* @param autoSave 是否自动保存 (默认true)
* @returns 是否成功消耗
*/
spendDiamond(amount: number, autoSave: boolean = true): boolean {
const currentDiamond = this.getGameProperty("diamond", 0);
if (currentDiamond < amount) {
console.warn(`[SMC]: 钻石不足,当前: ${currentDiamond}, 需要: ${amount}`);
return false;
}
this.addDiamond(-amount, autoSave);
return true;
}
/**
* 增加关卡进度
* @param amount 增加的关卡数 (默认1)
* @param autoSave 是否自动保存 (默认true)
*/
addMission(amount: number = 1, autoSave: boolean = true) {
const currentMission = this.getGameProperty("mission", 1);
const newMission = currentMission + amount;
this.setGameProperty("mission", newMission, autoSave);
console.log(`[SMC]: 关卡进度增加: ${currentMission} -> ${newMission} (+${amount})`);
// 计算章节和关卡等级
// this.vmdata.mission_data.chapter = Math.floor((newMission - 1) / 10) + 1
// this.vmdata.mission_data.level = ((newMission - 1) % 10) + 1
return newMission;
}
/**
* 增加分数
* @param score 分数
* @param autoSave 是否自动保存 (默认true)
*/
addScore(score: number, autoSave: boolean = true) {
const currentScore = this.getGameProperty("score", 0);
const newScore = currentScore + score;
this.setGameProperty("score", newScore, autoSave);
console.log(`[SMC]: 分数增加: ${currentScore} -> ${newScore} (+${score})`);
return newScore;
}
/**
* 重置游戏数据为默认值
* @param autoSave 是否自动保存 (默认true)
*/
resetGameData(autoSave: boolean = true) {
this.data = {
score: 888,
mission: 1,
gold: 100,
diamond: 100,
};
console.log("[SMC]: 游戏数据已重置为默认值:", this.data);
if (autoSave) {
this.saveGameData();
}
}
/**
* 检查本地存储状态(调试用)
*/
checkLocalStorage() {
const fightHeros = oops.storage.get("fight_heros");
const heros = oops.storage.get("heros");
const gameData = oops.storage.get("game_data");
console.log("[SMC]: 本地存储状态检查:");
console.log(" - fight_heros:", fightHeros ? "存在" : "不存在", fightHeros);
console.log(" - heros:", heros ? "存在" : "不存在", heros);
console.log(" - game_data:", gameData ? "存在" : "不存在", gameData);
return {
hasFightHeros: !!fightHeros,
hasHeros: !!heros,
hasGameData: !!gameData,
isFirstTime: !fightHeros && !heros && !gameData
};
}
}
export var smc: SingletonModuleComp = ecs.getSingleton(SingletonModuleComp);

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "58714c1c-3ffe-4ad1-959a-82e5dfeb2dc3",

View File

@@ -0,0 +1,49 @@
import { oops } from "db://oops-framework/core/Oops"
export class Test{
load_data_from_local() {
let local_data = this.get_local_data()
if(!local_data.data||!local_data.fight_heros||!local_data.heros||!local_data.items||!local_data.tals||!local_data.equips){
return this.init_local_data()
}
return local_data
}
get_local_data(){
let local_data ={
user_id: "local_debug",
openid: "local_debug",
regist_time: Date.now(),
data: JSON.parse(oops.storage.get("data")),
fight_heros: JSON.parse(oops.storage.get("fight_heros")),
heros: JSON.parse(oops.storage.get("heros")),
items: JSON.parse(oops.storage.get("items")),
tals: JSON.parse(oops.storage.get("tals")),
equips: JSON.parse(oops.storage.get("equips"))
}
return local_data
}
init_local_data(){
let init_data = {
data : {
score: 0, mission: 1, gold: 100, diamond: 100, meat: 0, exp: 0,
ghstone: 0, bhstone: 0, phlestone: 0, rhstone: 0, herocard: 0,
ckey: 0, skey: 0, gkey: 0,},
fight_heros: { 0: 0, 1: 0, 2: 0, 3: 0, 4: 0 },
heros: {
5001: { uuid: 5001, lv: 1 },
5005: { uuid: 5005, lv: 1 },
5007: { uuid: 5007, lv: 1 }
},
items: {},
tals: {},
equips: {}
}
oops.storage.set("data", JSON.stringify(init_data.data))
oops.storage.set("fight_heros", JSON.stringify(init_data.fight_heros))
oops.storage.set("heros", JSON.stringify(init_data.heros))
oops.storage.set("items", JSON.stringify(init_data.items))
oops.storage.set("tals", JSON.stringify(init_data.tals))
oops.storage.set("equips", JSON.stringify(init_data.equips))
return this.get_local_data()
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "893646a7-1cf0-4c80-8fe1-39ac111130fc",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "28d11009-6d68-462a-9880-8b31cf5975fd",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "ffda71d7-624d-40de-8c09-712edd44bfdc",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "6f6a81bc-e767-4001-b181-2c18c896cfd0",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "28ac0ad6-53bf-471a-9256-ae7c8ad351a7",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "14663cf6-fb92-4921-8ba9-c836b2667737",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "49217bd4-ee11-49f7-b404-e8d40478fa2d",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "bbef9ac6-154b-4e27-9c56-e964e27ef2d5",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "26aee2e6-ab33-4155-a0aa-221c6be8d030",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "167eb23c-6d7e-4e30-96ca-06fec16eeaa8",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "0388f0b8-c77d-4020-8b9a-dabf774f6502",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "bde4950f-acae-4c3e-a6a7-39248c34613d",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "bb894d46-7785-4e72-9314-8e384a338ab3",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "5fdc5c44-f438-4c0e-8c5c-a2673d49aafd",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "91ba5d4e-bef8-4b0d-8c64-7ce0f37e43d2",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "196aaacb-556c-4bb2-925c-9a70dc3e56fc",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "9f62614b-42c3-4f21-a3d6-68c9190082e8",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "b44c446b-ce5f-4079-ac42-269837dbf580",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "d26fa84f-22b4-4136-bb46-d7e978683365",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "cb9afa42-2112-471e-b86c-79407ba6abd4",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "0aefc30a-9392-4ada-b3d0-8c15625e8cfc",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "8ae6d033-ff0f-44d5-9ff7-c57751bd4ea1",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "4209bcee-3867-4c0b-83c9-a4eeee989328",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "7eb34351-e975-447f-bf07-0a2e5e00a2e6",

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"31289da2-91ea-4ffe-85f3-879a3ac7641d","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "31289da2-91ea-4ffe-85f3-879a3ac7641d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"d8a3d973-c3c2-449f-82bd-adb9f6d5149d","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "d8a3d973-c3c2-449f-82bd-adb9f6d5149d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -17,7 +17,6 @@ export default class HeroAnmComp extends Component{
stop () {
// this.spine?.clearTrack(0);
this._hasStop = true;
}
onAnimationFinished(type:Animation.EventType, state:AnimationState){

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "4ba4ac2e-cfcb-45df-8aea-e13919f56d52",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "846e0307-e55e-4bc3-a9db-b387c89ad671",

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"c9121e83-b457-492d-aa56-2119d79a3360","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "c9121e83-b457-492d-aa56-2119d79a3360",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"a03797e6-86f0-4771-b35c-045fe5e373bc","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "a03797e6-86f0-4771-b35c-045fe5e373bc",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"873f877e-4a89-4c12-8f03-8934f1651878","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "873f877e-4a89-4c12-8f03-8934f1651878",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"c1d7128f-5af5-4f7c-b4a1-6bb6fd4f12e0","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "c1d7128f-5af5-4f7c-b4a1-6bb6fd4f12e0",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "118ca580-773a-458b-8544-ab6c3cb2b376",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "6f882a1f-6f5a-4ef5-9ea0-21a0192c2785",

View File

@@ -12,8 +12,9 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
import { UIID } from "../common/config/GameUIConfig";
import { LoadingViewComp } from "./view/LoadingViewComp";
import { smc } from "../common/SingletonModuleComp";
import { WxCloudApi } from "../wx_clound_client_api/WxCloudApi";
import { WxCloudApi, UserGameData } from "../wx_clound_client_api/WxCloudApi";
import { GameDataSyncManager } from "../common/GameDataSyncManager";
import { Test } from "../common/Test";
// import {data} from "../data/data";
/**
@@ -47,18 +48,20 @@ export class Initialize extends ecs.Entity {
/** 加载自定义内容(可选) */
private loadCustom(queue: AsyncQueue) {
queue.push(async (next: NextFunction, params: any, args: any) => {
// 加载多语言对应字体
oops.res.load("language/font/" + oops.language.current, () => {
// 加载本地英雄数据
this.loadHeroDataFromLocal();
// 判断是否为微信客户端,是的话才加载云端数据
if (this.isWxClient()) {
this.loadWxDataFromCloud();
}
next();
});
try {
// 加载多语言对应字体
oops.res.load("language/font/" + oops.language.current, async () => {
// 统一的数据加载流程
await this.loadGameDataUnified();
next();
});
//加载精灵配置表
// oops.res.load("config/game/heros", next);
} catch (error) {
console.error("[Initialize]: 自定义内容加载失败:", error);
next(); // 即使失败也要继续,不阻塞游戏启动
}
});
}
@@ -96,42 +99,87 @@ export class Initialize extends ecs.Entity {
return typeof wx !== 'undefined' && typeof (wx as any).getSystemInfoSync === 'function';
}
private loadWxDataFromCloud() {
WxCloudApi.login().then(loginRes=>{
console.log("login res", loginRes);
});
}
/**
* 从本地存储加载游戏数据
* 统一的游戏数据加载流程
* 微信客户端:使用云端数据
* 非微信客户端:使用本地调试数据
*/
private loadHeroDataFromLocal() {
// 检查本地存储状态
const storageStatus = smc.checkLocalStorage();
if (storageStatus.isFirstTime) {
console.log("[Initialize]: 检测到首次启动游戏");
}
// 使用SingletonModuleComp的加载方法
// loadGameData方法已经包含了首次启动的处理逻辑
const success = smc.loadGameData();
if (success) {
console.log("[Initialize]: 游戏数据加载完成");
} else {
console.log("[Initialize]: 游戏数据加载失败,使用默认配置");
// 如果加载失败,初始化默认数据并保存
smc.initDefaultData();
smc.saveGameData();
}
// 再次检查存储状态,确认数据已保存
if (storageStatus.isFirstTime) {
const newStatus = smc.checkLocalStorage();
if (newStatus.hasFightHeros && newStatus.hasHeros && newStatus.hasGameData) {
console.log("[Initialize]: 首次启动数据保存成功");
private async loadGameDataUnified() {
try {
console.log("[Initialize]: 开始统一数据加载流程...");
if (this.isWxClient()) {
// 微信客户端:加载云端数据
console.log("[Initialize]: 检测到微信客户端,使用云端数据");
await this.loadFromCloud();
} else {
console.warn("[Initialize]: 首次启动数据保存可能失败");
// 非微信客户端:使用本地调试数据
console.log("[Initialize]: 非微信客户端,使用本地调试数据");
await this.loadFromLocalDebug();
}
} catch (error) {
console.error("[Initialize]: 统一数据加载失败:", error);
// 失败时使用默认数据 游戏需要退出
}
}
/**
* 从云端加载数据(微信客户端)
*/
private async loadFromCloud() {
try {
// 1. 初始化微信云环境
this.initWxCloudEnv();
// 2. 登录并获取云端数据
const loginResult = await WxCloudApi.login();
const response = loginResult.result;
if (response.code === 200) {
console.log("[Initialize]: 云端登录成功");
const cloudData = response.data;
// 3. 用云端数据覆盖本地数据
GameDataSyncManager.getInstance().overrideLocalDataWithRemote(cloudData, "云端");
} else {
console.warn("[Initialize]: 云端登录失败:", response.msg);
// 登录失败时使用本地数据 游戏需要退出
console.log("[Initialize]: 云端登录失败:", response.msg);
}
} catch (error) {
console.error("[Initialize]: 云端数据加载异常:", error);
// 异常时使用本地数据 游戏需要退出
}
}
/**
* 从本地调试数据加载(非微信客户端)
*/
private async loadFromLocalDebug() {
try {
// 使用本地调试API模拟云端接口
const loginResult = new Test().load_data_from_local()
// 用本地调试数据覆盖客户端数据
GameDataSyncManager.getInstance().overrideLocalDataWithRemote(loginResult, "本地调试");
} catch (error) {
console.error("[Initialize]: 本地调试数据加载异常:", error);
}
}
/**
* 初始化微信云环境
*/
private initWxCloudEnv() {
try {
// 请替换为您的实际云环境ID
const cloudEnvId = "cloud1-6gknw0qk911036d8"; // TODO: 配置您的云环境ID
WxCloudApi.init(cloudEnvId);
console.log("[Initialize]: 微信云环境初始化完成");
} catch (error) {
console.error("[Initialize]: 微信云环境初始化失败:", error);
}
}

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "ffbce42c-e99f-48a0-8e73-ea6b756af330",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "92429ca4-4e7c-450a-b706-c96e7c2568e3",

View File

@@ -364,11 +364,11 @@ export class CardComp extends CCComp {
this.reset_card()
}
cost_gold_check(){
if(smc.vmdata.mission_data.gold< this.cost_gold){
if(smc.vmdata.data.gold< this.cost_gold){
oops.gui.toast("[cardcomp]:金币不足", false);
return false
}
smc.vmdata.mission_data.gold-=this.cost_gold
smc.vmdata.data.gold-=this.cost_gold
return true
}
reset() {

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "e06b1406-878e-482d-99dd-46eb7ed2c7a8",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "ee99b110-f3d9-44b5-abc0-1d0b18dac6da",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "3d183133-c60d-44c0-933f-a629bea43331",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "df953176-a9fa-4f3e-865e-7956fccc4c52",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "d15fc8d4-c897-4a5c-a97c-b65114b41a69",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "d625f285-3706-4f2e-bf30-e03e34f16650",

View File

@@ -56,16 +56,17 @@ export class HInfoComp extends Component {
this.node.getChildByName("luck").active=lv == 0
}
uplevel(){
let hero_data = HeroInfo[this.h_uuid]
let lv=smc.heros[this.h_uuid].lv
let {experience,gold}=getUpgradeResources(lv)
if(smc.vmdata.mission_data.exp<=experience||smc.vmdata.mission_data.gold<=gold){
if(smc.vmdata.data.exp<=experience||smc.vmdata.data.gold<=gold){
oops.gui.toast("经验或金币不足")
return
}
smc.spendGameProperty("exp",experience)
smc.spendGameProperty("gold",gold)
smc.levelUpHero(this.h_uuid)
let result=smc.levelUpHero(this.h_uuid,experience,gold)
if(!result){
oops.gui.toast("网络出错了,升级失败,请重试")
return
}
this.update_data(this.h_uuid)
oops.message.dispatchEvent(GameEvent.UpdateHero, {})
}

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "f8dd2383-61ab-4cf9-9879-0d0fe2cd6c2f",

View File

@@ -38,9 +38,9 @@ export class HeroPageComp extends Component {
console.error("[Skill] 预制体加载失败:", path);
return;
}
const node = instantiate(prefab);
node.parent=parent
let hcard=node.getComponent(HCardUICom)!
const node = instantiate(prefab) as unknown as Node;
node.parent = parent;
let hcard = node.getComponent(HCardUICom)!;
hcard.update_data(uuid,{type:HeroConSet.INFO})
}
clear_heros(){

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "985ee2ae-8a25-4d68-a4f3-d909f5b2c225",

View File

@@ -24,6 +24,7 @@ export class HeroReadyCom extends Component {
}
update_hero(){
let hero = smc.fight_heros[this.slot]
console.log("[HeroReadyCom]hero",hero,smc.fight_heros,this.slot)
if(hero==0){
this.no_hero()
return

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "11781c25-08d5-41fc-af3e-b2dfd46dc5d7",

View File

@@ -50,9 +50,9 @@ export class HeroSelectCom extends Component {
console.error("[Skill] 预制体加载失败:", path);
return;
}
const node = instantiate(prefab);
node.parent=parent
let hcard=node.getComponent(HCardUICom)!
const node = instantiate(prefab) as unknown as Node;
node.parent = parent;
let hcard = node.getComponent(HCardUICom)!;
hcard.update_data(uuid,{type:HeroConSet.SELECT,slot:this.slot})
}

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "0c9b9c74-9486-4b43-b797-f602d26f2f1a",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "598155fc-f31b-4496-b1e4-82219435f425",

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"e0acc008-a00f-4682-ba4f-c47506bddf26","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "e0acc008-a00f-4682-ba4f-c47506bddf26",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "3748c53e-6b9b-479f-aba0-87fc123ce161",

View File

@@ -55,7 +55,7 @@ export class MissionComp extends CCComp {
oops.message.dispatchEvent(GameEvent.NewWave)
return
}
smc.addMission(1)
smc.addGameProperty("mission",1)
oops.message.dispatchEvent(GameEvent.FightEnd,{victory:true})
oops.gui.open(UIID.Victory,{victory:true})
}
@@ -135,7 +135,6 @@ export class MissionComp extends CCComp {
smc.vmdata.mission_data.in_fight=false
smc.vmdata.mission_data.fight_time=0
smc.vmdata.mission_data.level=0
smc.initReward()
console.log("[MissionComp]局内数据初始化",smc.vmdata.mission_data)
}

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"e7482754-5692-4425-9cc7-92a265d5958f","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "e7482754-5692-4425-9cc7-92a265d5958f",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -126,31 +126,8 @@ export class MissionHeroCompComp extends CCComp {
hero.load(pos,scale,uuid);
}
get_info_and_remove(fight_pos:number,uuid:number){
let info:any={ap:0,hp:0,lv:1,crit:0,crit_d:0,dod:0,dod_no:false,crit_no:false}
let heros=ecs.query(ecs.allOf(HeroModelComp))
if(heros.length>0){
let hero = heros[0]
let hv = hero.get(HeroViewComp)
info.ap=hv.ap
info.hp=hv.hp_max
info.lv=hv.lv
info.crit=hv.crit
info.crit_d=hv.crit_d
info.dod=hv.dod
info.dod_no=hv.dod_no
info.crit_no=hv.crit_no
hero.destroy()
return info
}
return info
}
do_hero_change(){
//金币加1
smc.vmdata.mission_data.gold+=1
}
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
reset() {

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "0e186bfb-2282-449d-9f50-757559af2d96",

View File

@@ -39,6 +39,7 @@ export class MissionHomeComp extends CCComp {
smc.syncData()
}
btn_func(e:string,data:any){
smc.syncDataFromLocal() //调试用,正式环境去掉
// console.log("[MissionHomeComp]:btn_func",e,data)
let page_heros=this.node.getChildByName("heros_page")
let page_shop=this.node.getChildByName("shop_page")

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "114984db-549a-4eea-a999-f26f64e79671",

View File

@@ -113,7 +113,7 @@ export class MissionMonCompComp extends CCComp { // 添加刷怪队列 - 使
// 根据新的关卡配置生成怪物
private generateMonstersFromStageConfig(monsterConfigs: any[]) {
const currentStage = smc.vmdata.mission_data.mission;
const currentStage = smc.vmdata.data.mission;
// 设置怪物总数
console.log("[MissionMonComp] generateMonstersFromStageConfig",monsterConfigs)

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "032d623d-38de-4117-9dcb-68ec75f124f5",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "f432a03f-6b3c-43a9-bdd8-845aeec7a019",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "463c788d-edc9-436c-b06e-b89e9fa9642f",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "2f2380b0-3fa7-48ee-8e30-24e5d718f91e",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "c68767c6-5154-4de2-97e5-895a76f9f8ea",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "b9f0df21-67f9-460a-8306-caf12042a78f",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "a31682ea-e44b-4122-b411-6761895ab6b0",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "e399b82b-77ce-4ae0-bb2d-81ae88e3fc91",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "6639aca8-e031-4a65-8094-d8e059cf26fe",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "753fb70a-638e-44d4-b736-f8696df44858",

View File

@@ -1 +1,11 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"7852ab4a-120b-4c93-9d76-9b48c382599f","files":[],"subMetas":{},"userData":{"simulateGlobals":[]}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "7852ab4a-120b-4c93-9d76-9b48c382599f",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,18 +1,14 @@
import { _decorator, Component, Node, sp } from 'cc';
import { _decorator, Component, Node } from 'cc';
const { ccclass, property ,} = _decorator;
@ccclass('light')
export class light extends Component {
private spine!: sp.Skeleton;
start() {
}
protected onLoad(): void {
this.spine = this.getComponent(sp.Skeleton)!;
this.spine.setCompleteListener(trackEntry => {
this.node.destroy()
});
}
update(deltaTime: number) {

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "fc960e39-45c0-41bf-8ff8-04a4acca0c38",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "36448c83-0bd9-495b-806d-6e7d640370e3",

View File

@@ -1,4 +1,4 @@
import { _decorator, Animation, Component, Node, sp } from 'cc';
import { _decorator, Animation, Component, Node } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('AnmEndCom')
@@ -11,16 +11,7 @@ export class AnmEndCom extends Component {
anim.on(Animation.EventType.FINISHED, this.onAnimationFinished, this);
}
if(this.node.getChildByName('anm')){
if(this.node.getChildByName('anm').getComponent('sp.Skeleton')){
var spine = this.node.getChildByName('anm').getComponent('sp.Skeleton') as sp.Skeleton;
console.log("has spine",spine)
spine.setCompleteListener((trackEntry) => {
this.onAnimationFinished()
console.log("[track %s][animation %s] complete: %s", trackEntry.trackIndex);
});
}
}
}
onAnimationFinished(){
this.node.destroy()

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "9a6c0cbd-2b5b-4ecd-85d3-c017de7a5b2a",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "5ebc6679-2a71-424f-bacf-48f20949fbd3",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "e7bac796-7cc3-47b4-904b-85a95cc15390",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "45646a08-c887-40db-85be-d1ce6b7442c3",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "a5e3c618-6636-439e-aa36-d4ee97793b18",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "49ffd76d-7069-4947-b170-62cd72619ede",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "65d6266f-bba6-4b98-8343-2a67642ec7eb",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "b1d8ed59-0347-4bb6-ab9f-86276714afca",

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "69132caf-02ba-40a8-a835-30baced39701",

View File

@@ -1,18 +1,13 @@
import { _decorator, Component, Node, sp } from 'cc';
import { _decorator, Component, Node } from 'cc';
const { ccclass, property ,} = _decorator;
@ccclass('once')
export class once extends Component {
private spine!: sp.Skeleton;
start() {
this.spine.setAnimation(0, "animation", true);
}
protected onLoad(): void {
this.spine = this.node.getChildByName("skill").getComponent(sp.Skeleton)!;
this.spine.setCompleteListener(trackEntry => {
if(this.node.isValid) this.node.active = false;
});
}
update(deltaTime: number) {

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"6e0a995d-16c1-4554-8f80-29394f24213b","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "6e0a995d-16c1-4554-8f80-29394f24213b",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,5 +1,5 @@
{
"ver": "4.0.23",
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "0f3c4261-15b1-4eda-b105-a81249ee116f",

View File

@@ -1 +1,9 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"f140b15c-7345-4364-818e-787001fb1c19","files":[],"subMetas":{},"userData":{}}
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "f140b15c-7345-4364-818e-787001fb1c19",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,443 @@
# WxCloudApi 客户端使用指南
## 📋 概述
`WxCloudApi` 是游戏客户端与微信云函数交互的统一接口层,提供了完整的类型安全和便捷的调用方法。
## 🚀 快速开始
### 1. 初始化
```typescript
// 在游戏启动时初始化云环境
WxCloudApi.init("your-cloud-env-id");
```
### 2. 用户登录
```typescript
// 用户登录,获取完整的游戏数据
const loginResult = await WxCloudApi.login();
if (loginResult.result.code === 200) {
const userData = loginResult.result.data;
console.log("用户ID:", userData.user_id);
console.log("金币:", userData.data.gold);
console.log("出战英雄:", userData.fight_heros);
}
```
## 🎮 基础游戏数据操作
### 获取游戏数据
```typescript
const gameData = await WxCloudApi.getGameData();
if (gameData.result.code === 200) {
console.log("当前金币:", gameData.result.data.gold);
console.log("当前钻石:", gameData.result.data.diamond);
}
```
### 增加金币
```typescript
// 方式1使用便捷方法
const result = await WxCloudApi.addGold(100);
// 方式2使用通用方法
const result = await WxCloudApi.addGameDataField('gold', 100);
if (result.result.code === 200) {
console.log("金币增加成功:", result.result.data);
}
```
### 消耗金币
```typescript
// 消耗金币(会检查是否足够)
const result = await WxCloudApi.spendGold(50);
if (result.result.code === 200) {
console.log("金币消耗成功");
} else if (result.result.code === -6) {
console.log("金币不足");
}
```
### 批量更新游戏数据
```typescript
const result = await WxCloudApi.updateGameData({
gold: 1000,
diamond: 200,
exp: 500
}, true); // true表示合并更新
```
## ⚔️ 出战英雄管理
### 获取出战英雄配置
```typescript
const fightHeros = await WxCloudApi.getFightHeros();
if (fightHeros.result.code === 200) {
console.log("出战配置:", fightHeros.result.data);
// { 0: 5001, 1: 5005, 2: 0, 3: 0, 4: 0 }
}
```
### 设置出战英雄
```typescript
// 将英雄5007设置到位置2
const result = await WxCloudApi.setFightHero(2, 5007);
if (result.result.code === 200) {
console.log("设置成功:", result.result.data);
}
// 移除位置2的英雄
await WxCloudApi.setFightHero(2, 0);
```
### 批量更新出战英雄
```typescript
const result = await WxCloudApi.updateFightHeros({
0: 5001,
1: 5005,
2: 5007
});
```
### 交换英雄位置
```typescript
// 交换位置0和位置2的英雄
const result = await WxCloudApi.swapFightHeros(0, 2);
```
### 获取激活的出战英雄
```typescript
const activeHeros = await WxCloudApi.getActiveFightHeros();
if (activeHeros.result.code === 200) {
const heros = activeHeros.result.data.active_heros;
heros.forEach(hero => {
console.log(`位置${hero.position}: 英雄${hero.hero_id}, 等级${hero.hero_data.lv}`);
});
}
```
## 🦸 英雄管理
### 获取所有英雄
```typescript
const heros = await WxCloudApi.getHeros();
if (heros.result.code === 200) {
Object.entries(heros.result.data).forEach(([heroId, heroData]) => {
console.log(`英雄${heroId}: 等级${heroData.lv}, 战力${heroData.power}`);
});
}
```
### 添加新英雄
```typescript
// 添加英雄(使用默认属性)
const result = await WxCloudApi.addHero(5008);
// 添加英雄(自定义属性)
const result = await WxCloudApi.addHero(5008, {
lv: 5,
exp: 1000,
star: 2,
power: 150
});
```
### 英雄升级
```typescript
// 升级1级
const result = await WxCloudApi.levelUpHero(5001);
// 升级3级
const result = await WxCloudApi.levelUpHero(5001, 3);
if (result.result.code === 200) {
console.log("升级成功:", result.result.data);
}
```
### 更新英雄属性
```typescript
// 批量更新
const result = await WxCloudApi.updateHero(5001, {
lv: 15,
exp: 2000,
star: 3
});
// 单个属性更新
const result = await WxCloudApi.setHeroProperty(5001, 'power', 200);
```
### 删除英雄
```typescript
const result = await WxCloudApi.deleteHero(5008);
if (result.result.code === -8) {
console.log("英雄正在出战中,无法删除");
}
```
## 🎒 库存管理
### 道具操作
```typescript
// 获取所有道具
const items = await WxCloudApi.getItems();
// 添加道具
const result = await WxCloudApi.addItem(1001, 10);
// 消耗道具
const result = await WxCloudApi.consumeItem(1001, 3);
// 获取指定道具数量
const itemInfo = await WxCloudApi.getInventoryItem('items', 1001);
console.log("道具1001数量:", itemInfo.result.data.count);
```
### 天赋操作
```typescript
// 获取所有天赋
const talents = await WxCloudApi.getTalents();
// 添加天赋点
const result = await WxCloudApi.addTalent(1001, 1);
// 消耗天赋点
const result = await WxCloudApi.consumeTalent(1001, 1);
```
### 装备操作
```typescript
// 获取所有装备
const equipments = await WxCloudApi.getEquipments();
// 添加装备
const result = await WxCloudApi.addEquipment(1001, 2);
// 消耗装备
const result = await WxCloudApi.consumeEquipment(1001, 1);
```
### 批量库存操作
```typescript
// 批量更新道具
const result = await WxCloudApi.updateInventory('items', {
1001: 20,
1002: 15,
1003: 10
});
// 获取拥有的道具列表(数量>0
const ownedItems = await WxCloudApi.getOwnedItems('items');
console.log("拥有的道具:", ownedItems.result.data.owned_items);
```
## 🔐 认证和版本管理
### 检查版本信息
```typescript
const versionInfo = await WxCloudApi.checkVersion();
if (versionInfo.result.code === 200) {
const compatibility = versionInfo.result.data.compatibility;
if (compatibility.needsUpgrade) {
console.log("需要升级数据:", compatibility.message);
// 可以选择自动升级
await WxCloudApi.upgradeUserData();
}
}
```
### 获取用户基本信息
```typescript
const userInfo = await WxCloudApi.getUserInfo();
if (userInfo.result.code === 200) {
console.log("用户信息:", userInfo.result.data);
}
```
## 🛠️ 错误处理
### 统一错误处理
```typescript
async function handleApiCall<T>(apiCall: Promise<CloudCallFunctionResult<CloudReturnType<T>>>) {
try {
const result = await apiCall;
const response = result.result;
switch (response.code) {
case 200:
console.log("操作成功:", response.data);
return response.data;
case -3:
console.error("参数错误:", response.msg);
break;
case -4:
console.error("用户未找到:", response.msg);
break;
case -5:
console.error("系统错误:", response.msg);
break;
case -6:
console.error("资源不足:", response.msg);
break;
default:
console.error("未知错误:", response.code, response.msg);
}
} catch (error) {
console.error("网络错误:", error);
}
return null;
}
// 使用示例
const gameData = await handleApiCall(WxCloudApi.getGameData());
```
### 资源不足处理示例
```typescript
async function trySpendGold(amount: number): Promise<boolean> {
const result = await WxCloudApi.spendGold(amount);
const response = result.result;
if (response.code === 200) {
console.log("金币消耗成功");
return true;
} else if (response.code === -6) {
console.log("金币不足,当前:", response.data?.current, "需要:", response.data?.required);
// 可以提示用户充值或其他操作
return false;
}
console.error("消耗失败:", response.msg);
return false;
}
```
## 📊 完整游戏流程示例
```typescript
export class GameDataManager {
// 游戏启动时初始化
public static async initialize() {
// 1. 初始化云环境
WxCloudApi.init("your-cloud-env-id");
// 2. 用户登录
const loginResult = await WxCloudApi.login();
if (loginResult.result.code !== 200) {
console.error("登录失败");
return false;
}
const userData = loginResult.result.data;
console.log("登录成功,用户数据:", userData);
// 3. 检查版本兼容性
const versionResult = await WxCloudApi.checkVersion();
if (versionResult.result.data.compatibility.needsUpgrade) {
console.log("正在升级数据...");
await WxCloudApi.upgradeUserData();
}
return true;
}
// 战斗结算
public static async settleBattle(rewards: {gold: number, exp: number, items: {[id: number]: number}}) {
try {
// 1. 增加金币和经验
await WxCloudApi.addGold(rewards.gold);
await WxCloudApi.addGameDataField('exp', rewards.exp);
// 2. 增加道具奖励
for (const [itemId, count] of Object.entries(rewards.items)) {
await WxCloudApi.addItem(parseInt(itemId), count);
}
console.log("战斗结算完成");
return true;
} catch (error) {
console.error("战斗结算失败:", error);
return false;
}
}
// 英雄升级
public static async upgradeHero(heroId: number, levels: number): Promise<boolean> {
// 假设每级需要100金币
const cost = levels * 100;
// 1. 检查金币是否足够
const spendResult = await WxCloudApi.spendGold(cost);
if (spendResult.result.code !== 200) {
console.log("金币不足,无法升级");
return false;
}
// 2. 升级英雄
const upgradeResult = await WxCloudApi.levelUpHero(heroId, levels);
if (upgradeResult.result.code === 200) {
console.log("英雄升级成功");
return true;
} else {
// 升级失败,退还金币
await WxCloudApi.addGold(cost);
console.error("英雄升级失败");
return false;
}
}
// 设置出战阵容
public static async setupFightTeam(heroIds: number[]): Promise<boolean> {
const fightHeros: Partial<FightHeros> = {};
// 最多5个位置
for (let i = 0; i < Math.min(heroIds.length, 5); i++) {
fightHeros[i] = heroIds[i];
}
// 清空剩余位置
for (let i = heroIds.length; i < 5; i++) {
fightHeros[i] = 0;
}
const result = await WxCloudApi.updateFightHeros(fightHeros);
return result.result.code === 200;
}
}
```
## 🎯 最佳实践
### 1. 错误处理
- 始终检查返回的 `code` 字段
- 对不同错误码进行相应处理
- 网络错误要有重试机制
### 2. 性能优化
- 批量操作优于多次单独操作
- 合理使用缓存,避免频繁请求
- 关键操作添加加载状态
### 3. 数据一致性
- 重要操作后及时同步本地数据
- 使用乐观锁机制处理并发
- 定期全量同步数据
### 4. 用户体验
- 操作前进行客户端验证
- 提供友好的错误提示
- 重要操作添加确认对话框
---
**版本**: 1.0.0
**更新时间**: 2024年
**维护者**: 游戏开发团队

View File

@@ -0,0 +1,11 @@
{
"ver": "1.0.1",
"importer": "text",
"imported": true,
"uuid": "f07f89b5-9257-48a8-a6ab-06f662e5e726",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -1,9 +1,92 @@
// 云函数返回类型定义
export type CloudReturnType<T = any> = {
code: number,// 200成功
msg?:string,
data?:T
code: number, // 200成功,其他都是失败
msg?: string, // 消息信息
data?: T, // 返回数据
timestamp?: number, // 时间戳
version?: string, // 数据版本
execution_time?: number // 执行时间(ms)
}
// 用户信息类型
export type UserInfo = {
user_id: string,
openid: string,
regist_time: number,
init_time?: number,
data_version?: string,
last_save_time?: number
}
// 完整用户数据类型
export type UserGameData = UserInfo & {
data: GameData,
fight_heros: FightHeros,
heros: Heros,
items: Items,
tals: Tals,
equips: Equips
}
// 基础游戏数据类型
export type GameData = {
score: number,
mission: number,
gold: number,
diamond: number,
meat: number,
exp: number,
ghstone: number, // 绿色英雄石
bhstone: number, // 蓝色英雄石
phlestone: number, // 紫色英雄石
rhstone: number, // 红色英雄石
herocard: number, // 英雄卡
ckey: number, // 铜钥匙
skey: number, // 银钥匙
gkey: number // 金钥匙
}
// 出战英雄类型
export type FightHeros = {
[position: number]: number // 位置 -> 英雄ID
}
// 英雄数据类型
export type HeroData = {
uuid: number,
lv: number,
exp?: number,
star?: number,
power?: number
}
export type Heros = {
[heroId: number]: HeroData
}
// 库存类型
export type Items = {
[itemId: number]: number
}
export type Tals = {
[talId: number]: number
}
export type Equips = {
[equipId: number]: number
}
// 版本兼容性检查结果
export type VersionCompatibility = {
compatible: boolean,
needsUpgrade: boolean,
message: string
}
// 库存类型枚举
export type InventoryType = 'items' | 'tals' | 'equips'
export class WxCloudApi{
/**
* @en init the cloud
@@ -16,30 +99,14 @@ export class WxCloudApi{
});
}
// ==================== 认证相关接口 ====================
/**
* @en Login to the cloud
* @zh 登录云
* @return 返回结果
* 参考:
* result.result = {
* code: number, // 200成功其他都是失败
* msg: string, // 如果失败,这里是失败原因等信息
* data: { // 成功才有
* openid: string, // 用户微信平台openid
* regist_time: number, // 时间戳,用户注册时间
* game_data: object, // 开发者自己保存的数据
* }
* }
* 如果这个泛型令你报错一般是因为你删了wx.api.d.ts导致请使用以下签名
* login():Promise<{result: CloudReturnType<{openid: string, regist_time: number, game_data: object}>}>
* 或者你是个“不拘小节”的老哥,可以用以下简洁版签名(参考上方的数据结构例子使用即可)
* login():Promise<any>
* @zh 用户登录,获取完整的用户和游戏数据
* @return Promise<CloudCallFunctionResult<CloudReturnType<UserGameData>>>
*/
public static async login(): Promise<CloudCallFunctionResult<CloudReturnType<{
openid:string,
regist_time:number,
game_data:any
}>>>{
public static async login(): Promise<CloudCallFunctionResult<CloudReturnType<UserGameData>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
@@ -49,29 +116,488 @@ export class WxCloudApi{
}
/**
* @en Save game data to the cloud
* @zh 把客户端数据写入云,此为全覆盖写入,请自行管理完整数据
* @return 返回结果
* 参考:
* result.result = {
* code: number, // 200成功其他都是失败
* msg: string, // 如果失败,这里是失败原因等信息
* data: {
* errMsg: "document.update:ok", // 数据库返回结果
* stats: {
* updated: number, // 更新了几条数据正常是1
* }
* }
* 如果这个泛型令你报错一般是因为你删了wx.api.d.ts导致请使用以下签名
* save(gameData: any): Promise<{resoult:CloudReturnType}>
* 或者你是个“不拘小节”的老哥,可以用以下简洁版签名(参考上方的数据结构例子使用即可)
* login():Promise<any>
* @en Get user basic info
* @zh 获取用户基本信息(不包含游戏数据
* @return Promise<CloudCallFunctionResult<CloudReturnType<UserInfo>>>
*/
public static async getUserInfo(): Promise<CloudCallFunctionResult<CloudReturnType<UserInfo>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "user_info"
}
});
}
/**
* @en Check data version compatibility
* @zh 检查数据版本兼容性
* @return Promise<CloudCallFunctionResult<CloudReturnType<{user_version: string, current_version: string, compatibility: VersionCompatibility}>>>
*/
public static async checkVersion(): Promise<CloudCallFunctionResult<CloudReturnType<{
user_version: string,
current_version: string,
compatibility: VersionCompatibility,
init_time: number,
regist_time: number,
last_save_time: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "version"
}
});
}
/**
* @en Force upgrade user data
* @zh 强制升级用户数据结构
* @return Promise<CloudCallFunctionResult<CloudReturnType<{old_version: string, new_version: string, upgrade_time: number} & UserGameData>>>
*/
public static async upgradeUserData(): Promise<CloudCallFunctionResult<CloudReturnType<{
old_version: string,
new_version: string,
upgrade_time: number
} & UserGameData>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "upgrade"
}
});
}
// ==================== 基础游戏数据接口 ====================
/**
* @en Get game data
* @zh 获取基础游戏数据(金币、钻石、经验等)
* @return Promise<CloudCallFunctionResult<CloudReturnType<GameData>>>
*/
public static async getGameData(): Promise<CloudCallFunctionResult<CloudReturnType<GameData>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "data_get"
}
});
}
/**
* @en Update game data
* @zh 批量更新基础游戏数据
* @param data 要更新的数据
* @param merge 是否合并更新默认true
* @return Promise<CloudCallFunctionResult<CloudReturnType<GameData>>>
*/
public static async updateGameData(data: Partial<GameData>, merge: boolean = true): Promise<CloudCallFunctionResult<CloudReturnType<GameData>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "data_update",
data: data,
merge: merge
}
});
}
/**
* @en Add to game data field
* @zh 增加指定字段的数值
* @param field 字段名
* @param amount 增加的数量
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: number, new_value: number, change: number}>>>
*/
public static async addGameDataField(field: keyof GameData, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
field: string,
old_value: number,
new_value: number,
change: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "data_add",
field: field,
amount: amount
}
});
}
/**
* @en Spend game data field
* @zh 消耗指定字段的数值(会检查是否足够)
* @param field 字段名
* @param amount 消耗的数量
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: number, new_value: number, change: number}>>>
*/
public static async spendGameDataField(field: keyof GameData, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
field: string,
old_value: number,
new_value: number,
change: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "data_spend",
field: field,
amount: amount
}
});
}
/**
* @en Set game data field
* @zh 直接设置某个字段的值
* @param field 字段名
* @param value 新的值
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: any, new_value: any}>>>
*/
public static async setGameDataField(field: keyof GameData, value: any): Promise<CloudCallFunctionResult<CloudReturnType<{
field: string,
old_value: any,
new_value: any
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "data_set",
field: field,
value: value
}
});
}
/**
* @en Reset game data
* @zh 重置基础游戏数据为默认值
* @return Promise<CloudCallFunctionResult<CloudReturnType<GameData>>>
*/
public static async resetGameData(): Promise<CloudCallFunctionResult<CloudReturnType<GameData>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "data_reset"
}
});
}
// 便捷方法:金币操作
/**
* @en Add gold
* @zh 增加金币
* @param amount 金币数量
*/
public static async addGold(amount: number) {
return await this.addGameDataField('gold', amount);
}
/**
* @en Spend gold
* @zh 消耗金币
* @param amount 金币数量
*/
public static async spendGold(amount: number) {
return await this.spendGameDataField('gold', amount);
}
// 便捷方法:钻石操作
/**
* @en Add diamond
* @zh 增加钻石
* @param amount 钻石数量
*/
public static async addDiamond(amount: number) {
return await this.addGameDataField('diamond', amount);
}
/**
* @en Spend diamond
* @zh 消耗钻石
* @param amount 钻石数量
*/
public static async spendDiamond(amount: number) {
return await this.spendGameDataField('diamond', amount);
}
// ==================== 出战英雄接口 ====================
/**
* @en Get fight heros
* @zh 获取出战英雄配置
* @return Promise<CloudCallFunctionResult<CloudReturnType<FightHeros>>>
*/
public static async getFightHeros(): Promise<CloudCallFunctionResult<CloudReturnType<FightHeros>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "fight_heros_get"
}
});
}
/**
* @en Set fight hero
* @zh 设置指定位置的出战英雄
* @param position 出战位置 (0-4)
* @param heroId 英雄ID0表示移除
* @return Promise<CloudCallFunctionResult<CloudReturnType<{position: number, old_hero_id: number, new_hero_id: number}>>>
*/
public static async setFightHero(position: number, heroId: number): Promise<CloudCallFunctionResult<CloudReturnType<{
position: number,
old_hero_id: number,
new_hero_id: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "fight_hero_set",
position: position,
hero_id: heroId
}
});
}
/**
* @en Update fight heros
* @zh 批量更新出战英雄配置
* @param fightHeros 出战英雄配置对象
* @return Promise<CloudCallFunctionResult<CloudReturnType<FightHeros>>>
*/
public static async updateFightHeros(fightHeros: Partial<FightHeros>): Promise<CloudCallFunctionResult<CloudReturnType<FightHeros>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "fight_heros_update",
fight_heros: fightHeros
}
});
}
/**
* @en Get active fight heros
* @zh 获取当前出战的英雄列表(不包含空位)
* @return Promise<CloudCallFunctionResult<CloudReturnType<{active_heros: Array<{position: number, hero_id: number, hero_data: HeroData}>, total_count: number}>>>
*/
public static async getActiveFightHeros(): Promise<CloudCallFunctionResult<CloudReturnType<{
active_heros: Array<{
position: number,
hero_id: number,
hero_data: HeroData
}>,
total_count: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "fight_heros_active"
}
});
}
/**
* @en Swap fight heros
* @zh 交换两个出战位置的英雄
* @param position1 位置1 (0-4)
* @param position2 位置2 (0-4)
* @return Promise<CloudCallFunctionResult<CloudReturnType<{position1: number, position2: number, hero1_moved_to: number, hero2_moved_to: number}>>>
*/
public static async swapFightHeros(position1: number, position2: number): Promise<CloudCallFunctionResult<CloudReturnType<{
position1: number,
position2: number,
hero1_moved_to: number,
hero2_moved_to: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "fight_heros_swap",
position1: position1,
position2: position2
}
});
}
/**
* @en Reset fight heros
* @zh 重置出战英雄配置为默认值
* @return Promise<CloudCallFunctionResult<CloudReturnType<FightHeros>>>
*/
public static async resetFightHeros(): Promise<CloudCallFunctionResult<CloudReturnType<FightHeros>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "fight_heros_reset"
}
});
}
// ==================== 英雄管理接口 ====================
/**
* @en Get all heros
* @zh 获取用户拥有的所有英雄数据
* @return Promise<CloudCallFunctionResult<CloudReturnType<Heros>>>
*/
public static async getHeros(): Promise<CloudCallFunctionResult<CloudReturnType<Heros>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "heros_get"
}
});
}
/**
* @en Get single hero
* @zh 获取指定英雄的详细数据
* @param heroId 英雄ID
* @return Promise<CloudCallFunctionResult<CloudReturnType<HeroData>>>
*/
public static async getHero(heroId: number): Promise<CloudCallFunctionResult<CloudReturnType<HeroData>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "hero_get",
hero_id: heroId
}
});
}
/**
* @en Add new hero
* @zh 添加新英雄到用户库存
* @param heroId 英雄ID
* @param heroData 英雄数据(可选)
* @return Promise<CloudCallFunctionResult<CloudReturnType<HeroData>>>
*/
public static async addHero(heroId: number, heroData?: Partial<HeroData>): Promise<CloudCallFunctionResult<CloudReturnType<HeroData>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "hero_add",
hero_id: heroId,
hero_data: heroData
}
});
}
/**
* @en Update hero
* @zh 批量更新英雄的多个属性
* @param heroId 英雄ID
* @param updateData 要更新的属性
* @return Promise<CloudCallFunctionResult<CloudReturnType<{old_data: HeroData, new_data: HeroData}>>>
*/
public static async updateHero(heroId: number, updateData: Partial<HeroData>): Promise<CloudCallFunctionResult<CloudReturnType<{
old_data: HeroData,
new_data: HeroData
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "hero_update",
hero_id: heroId,
update_data: updateData
}
});
}
/**
* @en Set hero property
* @zh 设置英雄的单个属性值
* @param heroId 英雄ID
* @param property 属性名
* @param value 属性值
* @return Promise<CloudCallFunctionResult<CloudReturnType<{hero_id: number, property: string, old_value: any, new_value: any}>>>
*/
public static async setHeroProperty(heroId: number, property: keyof HeroData, value: any): Promise<CloudCallFunctionResult<CloudReturnType<{
hero_id: number,
property: string,
old_value: any,
new_value: any
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "hero_property_set",
hero_id: heroId,
property: property,
value: value
}
});
}
/**
* @en Level up hero
* @zh 英雄升级指定级数
* @param heroId 英雄ID
* @param levels 升级级数默认1级
* @return Promise<CloudCallFunctionResult<CloudReturnType<{hero_id: number, property: string, old_value: number, new_value: number}>>>
*/
public static async levelUpHero(heroId: number, exp:number,gold:number,levels: number = 1): Promise<CloudCallFunctionResult<CloudReturnType<{
hero_id: number,
property: string,
old_value: number,
new_value: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "hero_levelup",
hero_id: heroId,
exp: exp,
gold:gold,
levels: levels
}
});
}
/**
* @en Delete hero
* @zh 删除指定英雄(会检查是否在出战阵容中)
* @param heroId 英雄ID
* @return Promise<CloudCallFunctionResult<CloudReturnType<HeroData>>>
*/
public static async deleteHero(heroId: number): Promise<CloudCallFunctionResult<CloudReturnType<HeroData>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "hero_delete",
hero_id: heroId
}
});
}
/**
* @en Get owned hero IDs
* @zh 获取用户拥有的所有英雄ID
* @return Promise<CloudCallFunctionResult<CloudReturnType<{hero_ids: number[], total_count: number}>>>
*/
public static async getOwnedHeroIds(): Promise<CloudCallFunctionResult<CloudReturnType<{
hero_ids: number[],
total_count: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "heros_owned"
}
});
}
// ==================== 兼容旧接口 ====================
/**
* @en Save game data to the cloud (Legacy)
* @zh 把客户端数据写入云,此为全覆盖写入,请自行管理完整数据(兼容旧接口)
* @param gameData 游戏数据
* @return Promise<CloudCallFunctionResult<CloudReturnType<{results: any[]}>>>
*/
public static async save(gameData: any): Promise<CloudCallFunctionResult<CloudReturnType<{
errMsg: string,
status:{
updated: number
}
results: any[]
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
@@ -81,4 +607,284 @@ export class WxCloudApi{
}
});
}
// ==================== 库存管理接口 (items, tals, equips) ====================
/**
* @en Get inventory
* @zh 获取指定类型的所有库存数据
* @param type 库存类型 ('items', 'tals', 'equips')
* @return Promise<CloudCallFunctionResult<CloudReturnType<Items | Tals | Equips>>>
*/
public static async getInventory(type: InventoryType): Promise<CloudCallFunctionResult<CloudReturnType<Items | Tals | Equips>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "inventory_get",
type: type
}
});
}
/**
* @en Get inventory item
* @zh 获取指定物品的数量
* @param type 库存类型
* @param itemId 物品ID
* @return Promise<CloudCallFunctionResult<CloudReturnType<{item_id: number, count: number}>>>
*/
public static async getInventoryItem(type: InventoryType, itemId: number): Promise<CloudCallFunctionResult<CloudReturnType<{
item_id: number,
count: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "inventory_item_get",
type: type,
item_id: itemId
}
});
}
/**
* @en Add inventory item
* @zh 增加指定物品的数量
* @param type 库存类型
* @param itemId 物品ID
* @param count 添加数量
* @return Promise<CloudCallFunctionResult<CloudReturnType<{item_id: number, old_count: number, new_count: number, added: number}>>>
*/
public static async addInventoryItem(type: InventoryType, itemId: number, count: number): Promise<CloudCallFunctionResult<CloudReturnType<{
item_id: number,
old_count: number,
new_count: number,
added: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "inventory_item_add",
type: type,
item_id: itemId,
count: count
}
});
}
/**
* @en Consume inventory item
* @zh 消耗指定数量的物品(会检查是否足够)
* @param type 库存类型
* @param itemId 物品ID
* @param count 消耗数量
* @return Promise<CloudCallFunctionResult<CloudReturnType<{item_id: number, old_count: number, new_count: number, added: number}>>>
*/
public static async consumeInventoryItem(type: InventoryType, itemId: number, count: number): Promise<CloudCallFunctionResult<CloudReturnType<{
item_id: number,
old_count: number,
new_count: number,
added: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "inventory_item_consume",
type: type,
item_id: itemId,
count: count
}
});
}
/**
* @en Set inventory item
* @zh 直接设置物品的数量
* @param type 库存类型
* @param itemId 物品ID
* @param count 新的数量
* @return Promise<CloudCallFunctionResult<CloudReturnType<{item_id: number, old_count: number, new_count: number}>>>
*/
public static async setInventoryItem(type: InventoryType, itemId: number, count: number): Promise<CloudCallFunctionResult<CloudReturnType<{
item_id: number,
old_count: number,
new_count: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "inventory_item_set",
type: type,
item_id: itemId,
count: count
}
});
}
/**
* @en Update inventory
* @zh 批量更新多个物品的数量
* @param type 库存类型
* @param data 更新数据对象
* @param merge 是否合并更新默认true
* @return Promise<CloudCallFunctionResult<CloudReturnType<Items | Tals | Equips>>>
*/
public static async updateInventory(type: InventoryType, data: Partial<Items | Tals | Equips>, merge: boolean = true): Promise<CloudCallFunctionResult<CloudReturnType<Items | Tals | Equips>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "inventory_update",
type: type,
data: data,
merge: merge
}
});
}
/**
* @en Reset inventory
* @zh 重置指定类型的库存为默认值
* @param type 库存类型
* @return Promise<CloudCallFunctionResult<CloudReturnType<Items | Tals | Equips>>>
*/
public static async resetInventory(type: InventoryType): Promise<CloudCallFunctionResult<CloudReturnType<Items | Tals | Equips>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "inventory_reset",
type: type
}
});
}
/**
* @en Get owned items
* @zh 获取数量大于0的物品列表
* @param type 库存类型
* @return Promise<CloudCallFunctionResult<CloudReturnType<{owned_items: Array<{item_id: number, count: number}>, total_types: number}>>>
*/
public static async getOwnedItems(type: InventoryType): Promise<CloudCallFunctionResult<CloudReturnType<{
owned_items: Array<{
item_id: number,
count: number
}>,
total_types: number
}>>> {
return await wx?.cloud.callFunction({
name: 'cocos_cloud',
data: {
cmd: "inventory_owned",
type: type
}
});
}
// ==================== 便捷方法:道具操作 ====================
/**
* @en Get items
* @zh 获取所有道具数据
*/
public static async getItems() {
return await this.getInventory('items');
}
/**
* @en Add item
* @zh 添加道具
* @param itemId 道具ID
* @param count 数量
*/
public static async addItem(itemId: number, count: number) {
return await this.addInventoryItem('items', itemId, count);
}
/**
* @en Consume item
* @zh 消耗道具
* @param itemId 道具ID
* @param count 数量
*/
public static async consumeItem(itemId: number, count: number) {
return await this.consumeInventoryItem('items', itemId, count);
}
// ==================== 便捷方法:天赋操作 ====================
/**
* @en Get talents
* @zh 获取所有天赋数据
*/
public static async getTalents() {
return await this.getInventory('tals');
}
/**
* @en Add talent
* @zh 添加天赋点
* @param talId 天赋ID
* @param count 数量
*/
public static async addTalent(talId: number, count: number) {
return await this.addInventoryItem('tals', talId, count);
}
/**
* @en Consume talent
* @zh 消耗天赋点
* @param talId 天赋ID
* @param count 数量
*/
public static async consumeTalent(talId: number, count: number) {
return await this.consumeInventoryItem('tals', talId, count);
}
// ==================== 便捷方法:装备操作 ====================
/**
* @en Get equipments
* @zh 获取所有装备数据
*/
public static async getEquipments() {
return await this.getInventory('equips');
}
/**
* @en Add equipment
* @zh 添加装备
* @param equipId 装备ID
* @param count 数量
*/
public static async addEquipment(equipId: number, count: number) {
return await this.addInventoryItem('equips', equipId, count);
}
/**
* @en Consume equipment
* @zh 消耗装备
* @param equipId 装备ID
* @param count 数量
*/
public static async consumeEquipment(equipId: number, count: number) {
return await this.consumeInventoryItem('equips', equipId, count);
}
// ==================== 其他便捷方法 ====================
/**
* @en Load game data (Legacy compatible)
* @zh 加载游戏数据(兼容旧接口)
*/
public static async load() {
return await this.login();
}
/**
* @en Get all game data at once
* @zh 一次性获取所有游戏数据
* @return Promise<CloudCallFunctionResult<CloudReturnType<UserGameData>>>
*/
public static async getAllGameData(): Promise<CloudCallFunctionResult<CloudReturnType<UserGameData>>> {
return await this.login();
}
}

Some files were not shown because too many files have changed in this diff Show More