Project1

标题: RPG Maker MV 中的 alias [打印本页]

作者: rpg-sheep    时间: 2015-11-12 21:10
标题: RPG Maker MV 中的 alias
本帖最后由 rpg-sheep 于 2015-11-13 15:00 编辑

众所周知,RPG Maker MV 更新后 javascript 取代了 Ruby
然而alias也随之而去……{:2_282:}
那么问题来了!怎么重定义方法!重定义方法是非常重要的一个环节,对于插件兼容性非常有用。
比如这么个代码
JAVASCRIPT 代码复制
  1. function test(){
  2. }
  3. test.prototype.hahah = function(){
  4.         alert("1122")
  5. }
  6. test.prototype.hahah()

这个代码只能输出一次1122,我想给hahah方法添加一段代码,让他再输出2222,但不改变hahah这个方法名,VA用alias可以轻松实现,然而MV呢?
JAVASCRIPT 代码复制
  1. function test(){
  2. }
  3. test.prototype.hahah = function(){
  4.         alert("1122")
  5. }
  6. test.prototype.hahah2 = test.prototype.hahah;
  7. test.prototype.hahah = function(){
  8.         this.hahah2()
  9.         alert("2222")
  10. }
  11. //位置1
  12. test.prototype.hahah()

把这段话复制到一个插件里并启用测试,可以输出1122和2222。实现了对test.hahah的重定义!
我如果想再加一段呢?在刚才的位置1加一段:
JAVASCRIPT 代码复制
  1. test.prototype.hahah3 = test.prototype.hahah;
  2. test.prototype.hahah = function(){
  3.         this.hahah3()
  4.         alert("2223")
  5. }

可以输出1122和2222,2223.完全没有压力,解决了多个插件同时加载防冲突的问题~

小结:
JAVASCRIPT 代码复制
  1. test.prototype.hahah2 = test.prototype.hahah;

等同于
RUBY 代码复制
  1. alias :hahah2 :hahah


应用:在Scene_Map里加一个窗口Window_XY_Mission:
JAVASCRIPT 代码复制
  1. Scene_Map.prototype.old_createDisplayObjects = Scene_Map.prototype.createDisplayObjects;
  2. Scene_Map.prototype.createDisplayObjects = function() {
  3.         this.old_createDisplayObjects();
  4.         this.XY_createMissionWindow();
  5. };
  6. Scene_Map.prototype.XY_createMissionWindow = function() {
  7.     this._XY_MissionWindow = new Window_XY_Mission();
  8.     this.addWindow(this._XY_MissionWindow);
  9. };

就成功在不冲突的情况下添加了窗口!(这里并没有贴出Window_XY_Mission的代码!)

语法解析:
JAVASCRIPT 代码复制
  1. test.prototype.hahah3 = test.prototype.hahah;//复制hahah方法到hahah3
  2. //错误范例:test.prototype.hahah3 = test.prototype.hahah();这里不能带括号,否则就是返回结果了
  3. test.prototype.hahah = function(){//覆盖原有hahah方法
  4.         this.hahah3();//注意这里一定要用this.hahah3(),不能用test.prototype.hahah3()!
  5.         /*这里详细解释一下为什么不能用:
  6.            如果你把这句替换成test.prototype.hahah3()然后测试,是可以实现的。
  7.            但是如果你实际应用的时候不用this.,会弹出TypeError:Cannot read property 'length' of undefined。
  8.            问题就出在这句上:你会发现很多地方都有类似这句的语句:Window_xxx.prototype = Object.create(Window_Base.prototype);
  9.            这玩意讲了很多人也听不懂,所以记住用this.就行啦
  10.         */
  11.         alert("2223");
  12. }


感谢@VIPArcher的提醒~关于有参数的方法直接像这样写上就可以了
JAVASCRIPT 代码复制
  1. function test(){
  2. }
  3. test.prototype.hahah = function(a,b){
  4.         alert(a+b);
  5. }
  6. test.prototype.hahah2 = test.prototype.hahah;
  7. test.prototype.hahah = function(a,b){
  8.         this.hahah2(a,b);
  9.         alert(a-b);
  10. }
  11. test.prototype.hahah3 = test.prototype.hahah;
  12. test.prototype.hahah = function(a,b){
  13.         this.hahah3(a,b);
  14.         alert(a*b);
  15. }
  16. test.prototype.hahah(1,2)
输出3,-1,2。
PS
什么?你看到了Window_XY_Mission?对的,小优(rpg_sheep)正在制作RPG Maker MV的任务插件!
作者: 汪汪    时间: 2015-11-12 21:36
觉得讲的很好...
作者: 苍刃君    时间: 2015-11-12 22:02
非程序猿表示完全不懂
作者: 墨凌羽    时间: 2015-11-13 00:14
我在想这真的等于么。。。
作者: VIPArcher    时间: 2015-11-13 11:46
本帖最后由 VIPArcher 于 2015-11-13 11:47 编辑

楼主不考虑一下带参数的姿势么?
JAVASCRIPT 代码复制
  1. var alias_method_name = old_method_name;
  2. old_method_name = function(name) {
  3.     alias_method_name.call(this,name);
  4.     console.log('喵呜炒鸡萌~');
  5. };

另外我完全不懂js,全是瞎糊的=。=
作者: 冷峻逸    时间: 2015-11-13 12:33
提示: 作者被禁止或删除 内容自动屏蔽
作者: qq420134293    时间: 2015-11-13 13:25
{:2_277:}你试一下可以传方法么?可以的话,自己写的时候以后第一个参数永远传方法,不就行了,类似于可以无限继承。
作者: WildDagger    时间: 2015-11-13 23:11
本帖最后由 WildDagger 于 2015-11-13 23:14 编辑

補充一下,Java Script每個函式都有個變數叫做「arguments」,這是一個陣列,會把呼叫這個函式時代入的參數全部存在裡面
跟參數有關的問題其實可以全部只用arguments變數來處理,就不用煩惱說多參數該怎麼辦了,至於呼叫的方式等等再提
(其實你可以試著在腳本寫下console.log(arguments[0])來看,那一定是第一個參數值)

另外就是關於繼承與別名的問題,Java Script也有call可以處理

簡單說若有一個函數叫做test.functionA,然後你要去增強functionA,又不希望functionA被完全取代掉
只要這樣寫就可以了
  1. var functionA_Alias = test.functionA;
  2. test.functionA = function() {
  3.     functionA_Alias.apply(this, arguments);

  4.     (其他程式碼)
  5. };
复制代码
簡單來說Java Script有call與apply這兩個function專用的方法
第一個參數是你要把誰塞進去充當函數內「this」的值,call之後就跟一般的函式一樣,依序寫入參數就可以,
但apply則是要求你第二個值必須是一個陣列,而apply會自動將陣列拆成參數依序帶入

也就是說functionA.call(this, a, b)和functionA.apply(this, [a, b])是一樣的意思
前者是你確定有哪些參數還有參數要依照甚麼次序帶入的時候可以使用,後者則是當你不確定有哪些參數的時候就可以選擇這個

另外Java Script的特性是你參數多給也無妨,反正如果參數指定3個,但該函式只用到前兩個的話,剩下那一個電腦就會自動當作沒看到而忽略掉。
作者: xjzsq    时间: 2015-12-25 18:40
我可不可以定义一个alias方法,然后代替这些脚本?
JS还没学好,所以请大神帮忙教一下,这样JS就更贴近RGSS3了
作者: grammy416    时间: 2015-12-25 18:43
xjzsq 发表于 2015-12-25 18:40
我可不可以定义一个alias方法,然后代替这些脚本?
JS还没学好,所以请大神帮忙教一下,这样JS就更贴近RGSS ...

完全没必要
作者: T-cog    时间: 2020-8-17 01:10
请问一种情况:当反复alias同一个方法时,每次的“别名”需要都不一样,是吗?
比如,你在给hahah方法扩展命令后,又想再次对其扩展命令。
test.prototype.hahah2 = test.prototype.hahah;
test.prototype.hahah = function(){
        this.hahah2()
        alert("2222")
}
我试了一下,第二次扩展时(再次对hahah扩展命令),不能用hahah2了。
似乎,一个安全的方法是,将所有同一个函数的扩展,放到同一个地方(同一个插件里)

请问楼主怎么看?




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1