RPG Maker MV 插件制作入门(2)
作者:广树·时间:2017-07-13 16:42:42·分类:JavaScript/jQuery/Vue
上回的制作入门(1)中,我们制作了一个在角色名字后面追加ID显示的简单插件。可以通过插件参数设定初始显示,然后通过插件指令来切换显示。
这次也继续上回,拓展这个插件。
将状态保存到存档文件中
上次制作的插件虽然准备了插件指令,但有一个缺点。就是无法保存在存档中,就算通过指令开关,只要游戏重启又会回到初始状态。
因此这次,要将show_id的值保存到存档中,这样就算重启游戏也能维持状态。
3种存档文件
RPG Maker MV所生成的游戏中,有以下三种存档文件。
config.rpgsave
file*.rpgsave
global.rpgsave
'config.rpgsave'是为了保存游戏设定的文件。标题画面以及游戏菜单的设置状态保存在这里。比如下面的设置画面。
被保存的数据如下。
'global.rpgsave' 是储存在存档选择画面中所使用的数据,在存档生成和更新时更新。比如对应下面的存档选择画面。
所保存的数据如下。
我们知道'file*.rpgsave' 是实际的存档文件,那么是否所有内容都存在其中?那么省略一部分,来粗略介绍下主要部分吧。
也就是说可以理解成游戏的存档文件就是将$game变量的值保存在里面。
利用哪个变量呢
这次又说了很长的前言呢...
既然知道这些 $game 变量被保存在存档里的话,就让我们利用吧!只要从中选择一个值来储存的话,就能任凭系统去读取保存了。
个人经常使用的是 $gameSystem ,所以这次也用这个吧。
关于保存时所使用的名字,需要考虑是否会和其他插件重名。这里推荐名称为,插件名或者名字前面追加数据种类。
实际处理
首先将使用 show_id 的部分进行拓展。
变更尽量少,一行就够了,仅仅将if的条件改变了而已。
增加的1行是将 $gameSystem 保存的值读取到f变量中处理。名称按照惯例为N定义的插件名加上"_show_id" 作为储存的变量名就行了。
然后if语句的判断,如果保存的值为空则 f 为 undefined ,所以作为替换将使用前面的 show_id 。如果有保存的值则使用保存的值。
使用保存值的部分是OK了,将值保存起来的处理还没有呢。就修正插件指令的部分吧。
嗯,这里的修正也不多呢。只是将$gameSystem设定的值替代掉show_id而已。
然后,这样就完成了对应存档了。补上一行,修改三行。仅此而已。
修正前是如下的样子
show_id 的初始值由插件参数指定
通过插件指令变更show_id的值
show_id的值无法保存
修正后效果如下
show_id的值由插件参数指定,以后不可以变更
通过插件指令改变$gameSystem.RTK_Test_show_id的值
实际执行的时候使用$gameSystem.RTK_Test_show_id的值
但是如果找不到的话就使用show_id的值
show_id的变量从主角变成了作为初始值的配角。作为替代使用了 $gameSystem.RTK_Test_show_id 的变量,因为包含在 $gameSystem 中,所以会被存档保存。
这样的话有一个好处,只要不使用插件指令的话就不会消费存档文件的空间。
稍微下点功夫吧
在前面的章节中我们能保存了。作为目的应该足够了。这个章节作为附赠,稍微下点小功夫。
现在所使用的结构里,show_id的变量反应在插件参数里吧。也就是说是在游戏开发的时候设定的值,实际游戏发布后就无法变更了。
以此为前提,为了更加节约存档文件空间,我们将代码变成这样。
如果和初始值相同的话就没有必要储存起来。
不需要的值用delete删除掉
这次的值只有一个,所以可能并不需要特地去删除掉。但是「良好礼节挂心中的代码」是很重要的,要经常有这样的意识,所以稍微下了点功夫介绍了下例子。
想要认真处理储存的情况
这次的例子里,利用$game的变量难免有点偷工。这里说下如何好好处理。
首先保存的时候,扩张以下存档生成处理比较好。
然后为了读取设定好的数据,扩张如下存档处理比较好。
追加插件的机能吧
难得机会,稍微追加下插件的机能吧。不仅仅是角色,追加敌人的ID显示吧!
战斗中,使用控制台来查找类。$game变量中 $gameTroop 有点像,作为起点吧。
那么,敌人的name函数扩张起来吧。首先在不追加的情况下做下扩张的准备工作。
在有时间的情况下,在这个状态下进行游戏测试。在自己对代码进行调试前,先看看扩张的代码对游戏有什么坏影响没,提前打个预防针。
不,实际上真的有哦。烦恼了几个小时,结果发现是简单的第一步就拼写错误导致失败不断,何等的犯糊涂...不,应该不只我会这样。
那么追写实际的代码吧。不过和写角色的情况差不多...
姑且,将使用的变量改成show_eid。所以在插件参数以及插件指令的部分也必须要扩张。
不过和角色差不多,这里就不细细说明代码了。最后会将代码全部丢上来,到时候再来确认追加的代码吧。
完成插件吧
那么,到此为止所说明的插件,结果也不错姑且就算完成了吧。
名字叫 'RTK_Test' 也不好呢。就改名'RTK_ShowID' 吧。在变更文件名的同时,别忘了修改最初N变量的定义。
帮助也很不充分(写着不包含插件指令,但是实际上是有的),需要各种追加和变更表述。
于是完成结果在这里 -> RTK_ShowID.js
因为有点长,可以借助GitHub的功能进行查看。源链接也可以储存下载js。
这就是插件开发相关的最低限度的说明。制作各种插件,尝试乐在其中吧!
那么,再会!
翻译自:https://github.com/yamachan/jgss-hack/blob/master/guide/plugin-dev-02.ja.md
这次也继续上回,拓展这个插件。
将状态保存到存档文件中
上次制作的插件虽然准备了插件指令,但有一个缺点。就是无法保存在存档中,就算通过指令开关,只要游戏重启又会回到初始状态。
因此这次,要将show_id的值保存到存档中,这样就算重启游戏也能维持状态。
3种存档文件
RPG Maker MV所生成的游戏中,有以下三种存档文件。
config.rpgsave
file*.rpgsave
global.rpgsave
'config.rpgsave'是为了保存游戏设定的文件。标题画面以及游戏菜单的设置状态保存在这里。比如下面的设置画面。
被保存的数据如下。
{ "alwaysDash":false, "commandRemember":false, "bgmVolume":100, "bgsVolume":100, "meVolume":100, "seVolume":100, }
'global.rpgsave' 是储存在存档选择画面中所使用的数据,在存档生成和更新时更新。比如对应下面的存档选择画面。
所保存的数据如下。
[ null, { "globalId":"RPGMV", "title":"RTK1 Dev1", "characters":[["Actor1",0],["Actor1",7],["Actor3",7],["Actor2",6]], "faces":[["Actor1",0],["Actor1",7],["Actor3",7],["Actor2",6]], "playtime":"00:00:04", "timestamp":1468556954489 }, { "globalId":"RPGMV", "title":"RTK1 Dev1", "characters":[["Actor1",0],["Actor1",7],["Actor3",7],["Actor2",6]], "faces":[["Actor1",0],["Actor1",7],["Actor3",7],["Actor2",6]], "playtime":"00:00:48", "timestamp":1468855189632 } ]
我们知道'file*.rpgsave' 是实际的存档文件,那么是否所有内容都存在其中?那么省略一部分,来粗略介绍下主要部分吧。
{ "system":{ "_saveEnabled":true, "_menuEnabled":true, "_encounterEnabled":true, "_formationEnabled":true, "_battleCount":0, "_winCount":0, // 中间省略 "@":"Game_System" }, "screen":{ "_brightness":255, "_fadeOutDuration":0, "_fadeInDuration":0, "_tone":[0,0,0,0], // 中间省略 "@":"Game_Screen" }, "timer":{"_frames":0,"_working":false,"@":"Game_Timer"}, "switches":{"_data":[null,null,null,null,null,null,null,null,true],"@":"Game_Switches"}, "variables":{"_data":[],"@":"Game_Variables"}, "selfSwitches":{"_data":{"1,3,A":true},"@":"Game_SelfSwitches"}, "actors":{ "_data":[ null, { "_actorId":1, "_name":"Harold", "_nickname":"Sword boy", "_hp":450, "_mp":90, "_tp":0, "_hidden":false, "_paramPlus":[0,0,0,0,0,0,0,0], // 中间省略 "@":"Game_Actor" },{ "_actorId":2, // 以下省略 },{ "_actorId":3, // 以下省略 { "_actorId":4, // 以下省略 } ], "@":"Game_Actors" }, "party":{ "_inBattle":false, "_gold":2000, "_steps":0, "_lastItem":{"_dataClass":"","_itemId":0,"@":"Game_Item"}, "_menuActorId":0, "_targetActorId":0, "_actors":[1,2,3,4], "_items":{"1":6,"2":1,"10":50,"11":2,"12":2,"13":2,"14":2}, "_weapons":{"1":1,"2":2,"4":10}, "_armors":{"3":1,"4":1}, "@":"Game_Party" }, "map":{ "_interpreter":{ "_depth":0, "_mapId":0, "_eventId":0, // 中间省略 "@":"Game_Interpreter" }, "_mapId":1, "_tilesetId":1, "_events":[ null, { "_x":4, "_y":1, // 中间省略 "@":"Game_Event" }, // 以下省略 ], "_commonEvents":[], // 中间省略 "@":"Game_Map" }, "player":{ "_x":4, "_y":4, // 中间省略 "_followers":{ "_visible":true, "_gathering":false, "_data":[ // 省略 ]," @":"Game_Followers" }, "_encounterCount":603, "@":"Game_Player" } }
也就是说可以理解成游戏的存档文件就是将$game变量的值保存在里面。
利用哪个变量呢
这次又说了很长的前言呢...
既然知道这些 $game 变量被保存在存档里的话,就让我们利用吧!只要从中选择一个值来储存的话,就能任凭系统去读取保存了。
个人经常使用的是 $gameSystem ,所以这次也用这个吧。
关于保存时所使用的名字,需要考虑是否会和其他插件重名。这里推荐名称为,插件名或者名字前面追加数据种类。
实际处理
首先将使用 show_id 的部分进行拓展。
var _Game_Actor_name = Game_Actor.prototype.name; Game_Actor.prototype.name = function() { var ret = _Game_Actor_name.call(this); var f = $gameSystem[N + "_show_id"]; if (f === undefined ? show_id : f) { return ret + ":" + this.actorId(); } else { return ret; } };
变更尽量少,一行就够了,仅仅将if的条件改变了而已。
增加的1行是将 $gameSystem 保存的值读取到f变量中处理。名称按照惯例为N定义的插件名加上"_show_id" 作为储存的变量名就行了。
然后if语句的判断,如果保存的值为空则 f 为 undefined ,所以作为替换将使用前面的 show_id 。如果有保存的值则使用保存的值。
使用保存值的部分是OK了,将值保存起来的处理还没有呢。就修正插件指令的部分吧。
var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand; Game_Interpreter.prototype.pluginCommand = function(command, args) { _Game_Interpreter_pluginCommand.call(this, command, args); if (command == N) { if (args[0] == "show_id") { if (args[1] == "on") { $gameSystem[N + "_show_id"] = 1; } else if (args[1] == "off") { $gameSystem[N + "_show_id"] = 0; } } } };
嗯,这里的修正也不多呢。只是将$gameSystem设定的值替代掉show_id而已。
然后,这样就完成了对应存档了。补上一行,修改三行。仅此而已。
修正前是如下的样子
show_id 的初始值由插件参数指定
通过插件指令变更show_id的值
show_id的值无法保存
修正后效果如下
show_id的值由插件参数指定,以后不可以变更
通过插件指令改变$gameSystem.RTK_Test_show_id的值
实际执行的时候使用$gameSystem.RTK_Test_show_id的值
但是如果找不到的话就使用show_id的值
show_id的变量从主角变成了作为初始值的配角。作为替代使用了 $gameSystem.RTK_Test_show_id 的变量,因为包含在 $gameSystem 中,所以会被存档保存。
这样的话有一个好处,只要不使用插件指令的话就不会消费存档文件的空间。
稍微下点功夫吧
在前面的章节中我们能保存了。作为目的应该足够了。这个章节作为附赠,稍微下点小功夫。
现在所使用的结构里,show_id的变量反应在插件参数里吧。也就是说是在游戏开发的时候设定的值,实际游戏发布后就无法变更了。
以此为前提,为了更加节约存档文件空间,我们将代码变成这样。
var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand; Game_Interpreter.prototype.pluginCommand = function(command, args) { _Game_Interpreter_pluginCommand.call(this, command, args); if (command == N) { if (args[0] == "show_id") { if (args[1] == "on") { if (show_id) { delete $gameSystem[N + "_show_id"]; } else { $gameSystem[N + "_show_id"] = 1; } } else if (args[1] == "off") { if (!show_id) { delete $gameSystem[N + "_show_id"]; } else { $gameSystem[N + "_show_id"] = 0; } } } } };
如果和初始值相同的话就没有必要储存起来。
不需要的值用delete删除掉
这次的值只有一个,所以可能并不需要特地去删除掉。但是「良好礼节挂心中的代码」是很重要的,要经常有这样的意识,所以稍微下了点功夫介绍了下例子。
想要认真处理储存的情况
这次的例子里,利用$game的变量难免有点偷工。这里说下如何好好处理。
首先保存的时候,扩张以下存档生成处理比较好。
var _DataManager_makeSaveContents = DataManager.makeSaveContents; DataManager.makeSaveContents = function() { var contents = _DataManager_makeSaveContents.call(this); // 这里将自己的数据设定成contents return contents; };
然后为了读取设定好的数据,扩张如下存档处理比较好。
var _DataManager_extractSaveContents = DataManager.extractSaveContents; DataManager.extractSaveContents = function(contents) { var ret = _DataManager_extractSaveContents.call(this, contents); // 这里将会从contents中读取数据 return ret; };
追加插件的机能吧
难得机会,稍微追加下插件的机能吧。不仅仅是角色,追加敌人的ID显示吧!
战斗中,使用控制台来查找类。$game变量中 $gameTroop 有点像,作为起点吧。
Game_Enemy.prototype.name = function() { return this.originalName() + (this._plural ? this._letter : ''); };
this.members().forEach(function(enemy) { var name = enemy.originalName(); if (this._namesCount[name] >= 2) { enemy.setPlural(true); } }, this);
那么,敌人的name函数扩张起来吧。首先在不追加的情况下做下扩张的准备工作。
var _Game_Enemy_name = Game_Enemy.prototype.name; Game_Enemy.prototype.name = function() { var ret = _Game_Enemy_name.call(this); return ret; };
在有时间的情况下,在这个状态下进行游戏测试。在自己对代码进行调试前,先看看扩张的代码对游戏有什么坏影响没,提前打个预防针。
不,实际上真的有哦。烦恼了几个小时,结果发现是简单的第一步就拼写错误导致失败不断,何等的犯糊涂...不,应该不只我会这样。
那么追写实际的代码吧。不过和写角色的情况差不多...
var _Game_Enemy_name = Game_Enemy.prototype.name; Game_Enemy.prototype.name = function() { var ret = _Game_Enemy_name.call(this); var f = $gameSystem[N + "_show_eid"]; if (f === undefined ? show_eid : f) { return ret + ":" + this.enemyId(); } else { return ret; } };
姑且,将使用的变量改成show_eid。所以在插件参数以及插件指令的部分也必须要扩张。
不过和角色差不多,这里就不细细说明代码了。最后会将代码全部丢上来,到时候再来确认追加的代码吧。
完成插件吧
那么,到此为止所说明的插件,结果也不错姑且就算完成了吧。
名字叫 'RTK_Test' 也不好呢。就改名'RTK_ShowID' 吧。在变更文件名的同时,别忘了修改最初N变量的定义。
帮助也很不充分(写着不包含插件指令,但是实际上是有的),需要各种追加和变更表述。
于是完成结果在这里 -> RTK_ShowID.js
因为有点长,可以借助GitHub的功能进行查看。源链接也可以储存下载js。
这就是插件开发相关的最低限度的说明。制作各种插件,尝试乐在其中吧!
那么,再会!
翻译自:https://github.com/yamachan/jgss-hack/blob/master/guide/plugin-dev-02.ja.md