-游戏存档系统实现)
坦克大战游戏开发实战(十九)-游戏存档系统实现前言游戏存档系统是游戏开发的重要组成部分它允许玩家保存游戏进度随时继续游戏。本文将详细讲解游戏存档系统的设计与实现包括存档管理器、多存档槽、自动存档、数据持久化等核心内容。存档系统的重要性进度保存保存玩家游戏进度避免重复游玩时间灵活玩家可以随时中断和继续游戏数据安全确保存档数据不丢失多存档支持支持多个存档方便管理存档系统存档管理器存档槽位数据持久化保存功能加载功能槽位1槽位2槽位3Preferences文件存储一、存档数据结构1.1 存档数据接口exportinterfaceSaveData{version:string;// 存档版本timestamp:number;// 保存时间戳level:number;// 当前关卡score:number;// 当前得分lives:number;// 当前生命enemies:number;// 剩余敌人playTime:number;// 游戏时长playerX:number;// 玩家X坐标playerY:number;// 玩家Y坐标playerDirection:number;// 玩家方向}1.2 存档槽位接口exportinterfaceSaveSlot{id:number;// 槽位IDname:string;// 槽位名称data:SaveData|null;// 存档数据isEmpty:boolean;// 是否为空}二、存档管理器实现2.1 单例模式exportclassSaveManager{privatestaticinstance:SaveManager;// 存档配置privatereadonlySAVE_VERSION1.0.0;privatereadonlyMAX_SLOTS3;privatereadonlyPREFERENCES_NAMEtank_battle_save;// 存档槽位privateslots:Mapnumber,SaveSlotnewMap();privatepreferencesInstance:preferences.Preferences|nullnull;privateconstructor(){this.initSlots();}staticgetInstance():SaveManager{if(!SaveManager.instance){SaveManager.instancenewSaveManager();}returnSaveManager.instance;}}2.2 初始化存档槽位/** * 初始化存档槽位 */privateinitSlots():void{for(leti1;ithis.MAX_SLOTS;i){this.slots.set(i,{id:i,name:存档${i},data:null,isEmpty:true});}}三、存档保存实现3.1 保存游戏/** * 保存游戏 */asyncsaveGame(slotId:number,data:SaveData):Promiseboolean{if(slotId1||slotIdthis.MAX_SLOTS){console.error(无效的存档槽位:,slotId);returnfalse;}if(!this.preferencesInstance){console.error(Preferences未初始化);returnfalse;}try{// 添加版本和时间戳constsaveData:SaveData{...data,version:this.SAVE_VERSION,timestamp:Date.now()};// 保存到PreferencesconstsaveJsonJSON.stringify(saveData);awaitthis.preferencesInstance.put(slot_${slotId},saveJson);awaitthis.preferencesInstance.flush();// 更新内存中的槽位数据constslotthis.slots.get(slotId);if(slot){slot.datasaveData;slot.isEmptyfalse;}console.info(游戏已保存到存档${slotId});returntrue;}catch(error){console.error(保存游戏失败:,error);returnfalse;}}3.2 自动存档/** * 自动存档 */asyncautoSave(data:SaveData):Promiseboolean{// 自动存档使用特殊槽位槽位1returnawaitthis.saveGame(1,data);}/** * 快速保存 */asyncquickSave(data:SaveData):Promiseboolean{returnawaitthis.saveGame(1,data);}四、存档加载实现4.1 加载游戏/** * 加载游戏 */asyncloadGame(slotId:number):PromiseSaveData|null{if(slotId1||slotIdthis.MAX_SLOTS){console.error(无效的存档槽位:,slotId);returnnull;}constslotthis.slots.get(slotId);if(!slot||slot.isEmpty||!slot.data){console.error(存档槽位为空:,slotId);returnnull;}console.info(从存档${slotId}加载游戏);returnslot.data;}4.2 快速加载/** * 快速加载 */asyncquickLoad():PromiseSaveData|null{returnawaitthis.loadGame(1);}五、存档管理功能5.1 删除存档/** * 删除存档 */asyncdeleteSave(slotId:number):Promiseboolean{if(slotId1||slotIdthis.MAX_SLOTS){console.error(无效的存档槽位:,slotId);returnfalse;}if(!this.preferencesInstance){console.error(Preferences未初始化);returnfalse;}try{// 从Preferences删除awaitthis.preferencesInstance.delete(slot_${slotId});awaitthis.preferencesInstance.flush();// 更新内存中的槽位数据constslotthis.slots.get(slotId);if(slot){slot.datanull;slot.isEmptytrue;}console.info(存档${slotId}已删除);returntrue;}catch(error){console.error(删除存档失败:,error);returnfalse;}}5.2 获取存档信息/** * 获取存档槽位信息 */getSlot(slotId:number):SaveSlot|undefined{returnthis.slots.get(slotId);}/** * 获取所有存档槽位 */getAllSlots():SaveSlot[]{constslotArray:SaveSlot[][];for(leti1;ithis.MAX_SLOTS;i){constslotthis.slots.get(i);if(slot){slotArray.push(slot);}}returnslotArray;}六、数据持久化6.1 Preferences存储HarmonyOS使用Preferences进行数据持久化/** * 初始化Preferences */asyncinitPreferences(context:Context):Promisevoid{try{this.preferencesInstanceawaitpreferences.getPreferences(context,this.PREFERENCES_NAME);awaitthis.loadAllSlots();}catch(error){console.error(初始化Preferences失败:,error);}}6.2 加载所有存档/** * 加载所有存档槽位 */privateasyncloadAllSlots():Promisevoid{if(!this.preferencesInstance){return;}for(leti1;ithis.MAX_SLOTS;i){try{constsaveJsonawaitthis.preferencesInstance.get(slot_${i},);if(saveJson){constsaveDataJSON.parse(saveJsonasstring)asSaveData;constslotthis.slots.get(i);if(slot){slot.datasaveData;slot.isEmptyfalse;}}}catch(error){console.error(加载存档槽位${i}失败:,error);}}}七、版本兼容性7.1 版本检查/** * 检查存档版本兼容性 */isCompatible(data:SaveData):boolean{// 简单的版本检查returndata.versionthis.SAVE_VERSION;}7.2 数据迁移如果版本不兼容需要进行数据迁移/** * 迁移存档数据 */migrateData(oldData:any):SaveData{// 根据版本号进行数据迁移// 这里可以实现版本升级逻辑returnoldDataasSaveData;}八、存档UI集成8.1 存档列表显示/** * 获取存档摘要信息 */getSaveSummary(slotId:number):string{constslotthis.slots.get(slotId);if(!slot||slot.isEmpty||!slot.data){return空存档;}constdataslot.data;consttimethis.formatSaveTime(data.timestamp);return[关卡${data.level},得分${data.score},生命${data.lives},时间${time}].join( | );}8.2 时间格式化/** * 格式化存档时间 */formatSaveTime(timestamp:number):string{constdatenewDate(timestamp);constyeardate.getFullYear();constmonth(date.getMonth()1).toString().padStart(2,0);constdaydate.getDate().toString().padStart(2,0);consthourdate.getHours().toString().padStart(2,0);constminutedate.getMinutes().toString().padStart(2,0);return${year}-${month}-${day}${hour}:${minute};}九、错误处理9.1 错误类型存档系统可能遇到的错误存储失败Preferences写入失败读取失败Preferences读取失败数据损坏存档数据损坏版本不兼容存档版本不匹配9.2 错误处理策略try{// 保存操作awaitthis.saveGame(slotId,data);}catch(error){console.error(存档操作失败:,error);// 可以选择// 1. 重试操作// 2. 使用备用存储// 3. 提示用户}十、总结游戏存档系统是游戏开发的重要组成部分。本文详细讲解了存档管理器、多存档槽、自动存档、数据持久化等核心内容为游戏提供了完整的存档功能。关键要点多存档槽支持多个存档方便管理自动存档自动保存游戏进度数据持久化使用Preferences进行数据存储版本兼容处理存档版本兼容性问题错误处理完善的错误处理机制系列文章导航下期预告坦克大战游戏开发实战(二十)-性能优化策略总结