我们修改obj_controller,在create事件里,最下面增加两行代码:
game_data=ds_map_create(); save_file="isolation.sav";
上面的代码表示,我们创建了一个数据结构,它的文件名为isolation.sav,当然这个后缀名可以自定义。
要从存档中加载和保存数据,我们将使用一些自定义函数。基本上,游戏保存的机制不外乎这两种。一种是每次你进入房间都会存档,另外一种是你在存档点时才保存。 因此,为了在不重写大量代码的情况下尽可能实现功能,我们定义了两个函数来完成这项工作。
首先创建函数叫save_game,GMS2在2.3以上的版本里,代码如下
function save_game(){ ds_map_replace_list(obj_controller.game_data,"player-items",obj_player.items); ds_map_replace_map(obj_controller.game_data,"player-equipped",obj_player.equipped); ds_map_replace(obj_controller.game_data,"player-x",obj_player.x); ds_map_replace(obj_controller.game_data,"player-y",obj_player.y); ds_map_replace(obj_controller.game_data,"player-hp",obj_player.hp); ds_map_replace(obj_controller.game_data,"player-can_dash",obj_player.can_dash); ds_map_replace(obj_controller.game_data,"player-can_jump",obj_player.can_wall_jump); ds_map_replace(obj_controller.game_data,"room",room_get_name(room)); var str_save=json_encode(obj_controller.game_data); var file=file_text_open_write(obj_controller.save_file); file_text_write_string(file,str_save); file_text_close(file); }
上面的代码,是把obj_player里关键的信息,比如,玩家的坐标,道具,装备,血量等参数存入到game_data这个DS MAP数据结构里。然后把它用json_encode转化成JSON结构,存入到文件里。
然后,再建一个函数叫load_game,代码如下
function load_game(){ if not file_exists(obj_controller.save_file) { return false; } ds_map_destroy(obj_controller.game_data); var file=file_text_open_read(obj_controller.save_file); var str_data=file_text_read_string(file); game_data=json_decode(str_data); file_text_close(file); obj_player.items=ds_list_create(); obj_player.equipped=ds_map_create(); obj_player.items=ds_map_find_value(obj_controller.game_data,"player-items"); obj_player.equipped=ds_map_find_value(obj_controller.game_data,"player-equipped"); obj_player.x=ds_map_find_value(obj_controller.game_data,"player-x"); obj_player.y=ds_map_find_value(obj_controller.game_data,"player-y"); obj_player.hp=ds_map_find_value(obj_controller.game_data,"player-hp"); obj_player.can_dash=ds_map_find_value(obj_controller.game_data,"player-can_dash"); obj_player.can_wall_jump=ds_map_find_value(obj_controller.game_data,"player-can_wall_jump"); room_restart(); var rm=ds_map_find_value(obj_controller.game_data,"room"); room_goto(asset_get_index(rm)); }
上面的代码,表示我们检测是否有存档存在,否那就不装入数据,返回false.
我们每次在装入数据前,都要重建一下数据结构,保证结构干净。后面就是依次根据键查到值,分配给obj_player的变量上。
最后,我们修改一下菜单项,在obj_controller的create事件里,修改代码
options=["RESUME","LOAD GAME","NEW GAME","QUIT"];
增加了load game这个选项。
修改step事件,在菜单代码区,找到后修改如下
if(enter_pressed) { switch(menu_index) { case 0://RESUME global.game_state=states.playing; instance_activate_all(); menu_open=false; global.can_pause=true; break; case 1://LOAD GAME load_game(); break; case 2://new game game_restart(); break; case 3: game_end(); break; } }
游戏中,当玩家站在检查点时,就自动保存,这也意味着载入存档后,也是从检查点继续。增加一个对象obj_checkpoint,赋予贴图spr_checkpoint_inactive。添加create事件,增加一行代码
already_saved=false;
这个变量可以控制,每次碰到检查点后,只存入一次。
增加step事件,填写如下代码
if place_meeting(x,y,obj_player) { if already_saved exit; sprite_index=spr_checkpoint_active; already_saved=true; save_game(); } else { sprite_index=spr_checkpoint_inactive; already_saved=false; }
这样游戏的保存功能就完成了,测试一下,把检查点放到房间里,效果如下
测试后,发现拾取的道具,会在存档读取后再次生成,这是一个BUG,要如何修复呢?
暂无关于此日志的评论。