单机游戏中涉及到存档关联数据的注意事项
单机游戏通常有两种类型的数据,全局数据与存档数据
前言
单机游戏在写数据存储过程需要注意全局数据与存档数据。
全局数据主要用于类似游戏成就、图鉴等与存档不关联的部分。
存档数据主要用于玩家背包、金币等不同存档有不同数据的部分。
打开游戏、新的游戏、读取存档数据被还原
默认情况下,定义的变量值将会在玩家打开游戏、新的游戏、读档等情况还原,因此我们需要写不同的监听。
确保玩家在打开游戏、读档情况下还原已经变更的数据。
全局数据事件监听
需要在玩家开始游戏、读取存档写一个事件监听,确保玩家得到的数据都是正确的
以AVG-星之瞳模板的CG为例,先定义 ___myCG
使用 regSaveCustomGlobalData
注册全局数据
CustomCommand1.ts
// -- 注册CG图鉴的全局数据
SinglePlayerGame.regSaveCustomGlobalData("___myCG", Callback.New(() => {
return WorldData.myCG;
}, null));
之后需要定义打开游戏、读档情况下获取全局数据
CustomCommand1.ts
// -- 监听游戏初始化同步自定义数据
EventUtils.addEventListener(ClientWorld, ClientWorld.EVENT_INITED, Callback.New(snycCustomGlobalData, null), true);
// -- 监听读档后同步自定义数据
EventUtils.addEventListener(SinglePlayerGame, SinglePlayerGame.EVENT_ON_AFTER_RECOVERY_DATA, Callback.New(snycCustomGlobalData, null), false);
function snycCustomGlobalData() {
let myCG = SinglePlayerGame.getSaveCustomGlobalData("___myCG");
if (myCG) WorldData.myCG = myCG;
}
最终,由于是全局数据,因此建议玩家每次触发数据变更情况下执行一次存档全局数据
CustomCommand1.ts
export function customCommand_7(commandPage: CommandPage, cmd: Command, trigger: CommandTrigger, triggerPlayer: ClientPlayer, playerInput: any[], p: CustomCommandParams_7): void {
// 存在该CG设定的话,加入至库存
if (GameData.getModuleData(1, p.cg)) {
if (WorldData.myCG.indexOf(p.cg) == -1) WorldData.myCG.push(p.cg);
// 立刻储存全局数据(与存档无关)
SinglePlayerGame.saveGlobalData(null);
}
}
存档数据事件监听
监听方法与全局数据类似,只是执行的函数不同且不需要考虑打开游戏情况。
因为打开游戏时,玩家还未进入游戏存档。
如果你的数据存储在世界设定、玩家设定里面,可以不用专门写事件监听,将会自动处理。
以下我将定义一个 CustomData 用于存储自定义变更的存档数据。
CustomData.ts
class CustomData{
static playerData = null
}
接下来用法与全局数据的监听类似。
CustomData.ts
// -- 注册存档数据
SinglePlayerGame.regSaveCustomData("__customDataPlayerData", Callback.New(() => {
return CustomData.playerData;
}, null));
CustomData.ts
// -- 监听读档后同步自定义数据
EventUtils.addEventListener(SinglePlayerGame, SinglePlayerGame.EVENT_ON_AFTER_RECOVERY_DATA, Callback.New(CustomDrawTitle.snycCustomGlobalData, null), false);
static snycCustomGlobalData() {
const playerData = SinglePlayerGame.getSaveCustomData("__customDataPlayerData");
if (playerData) CustomData.playerData = playerData;
}