じ☆ve冰风 发表于 2024-4-19 18:35:08

【新手互助】利用Mix-in(糅合)构建低耦合脚本

写在最前:以下观点来源于新手对RGSS脚本系统的一些浅显认知,希望能够给其他新手一些启发;牛人请直接跳过。如感觉不妥,请善意的指出;对于自认为很牛的无故拍砖者,一律鄙视!
原文链接:http://rpg.blue/home.php?mod=spa ... id=47826&id=689

include(module ... ) 对指定模块的性质(方法或常数)进行添加。返回 self。include 正是为实现 Mix-in(糅合)功能而设计的,而 Mix-in 取代了多重继承。
以上为RM中针对于关键字include的官方解释,本篇后续的内容亦是围绕此关键字展开。
Train_Actor是我接触RGSS以来遇到的第一个脚本系统,原帖可参见本坛脚本库,我空间里也有。用过的人应该都知道,只要借助于它便可轻易的实现角色跟随的特效。而引入此脚本的方法也很简单,只要在Main之前插入一段新脚本页,全部内容Copy即可。可谓便捷、经典。

第一次用这个脚本的时候觉得很神奇:该脚本完全独立,而系统是如何在恰当时机自动调用这个新增脚本内部方法的呢?经过一些简单的验证之后,终于渐渐发现了问题所在。

不知大家有没有留意到,该脚本的末端,也就是在module Train_Actor声明完毕之后,还有如下代码:

class Game_Party
include Train_Actor::Game_Party_Module
end
class Game_Player
include Train_Actor::Game_Player_Module
end
class Spriteset_Map
include Train_Actor::Spriteset_Map_Module
end
class Scene_Map
include Train_Actor::Scene_Map_Module
end

结合官方对于include的解释,不难猜想,这种独立脚本的自动调用机制即是由此而来。

所谓“对指定模块的性质(方法或常数)进行添加”,简单而言,也就是让自己脚本中已定义模块的方法或常数,成为指定模块中相应方法的逻辑补充。即是说,系统在调用原有模块内部方法的同时,会自动对已经被include至该模块的其他模块内部方法或常数进行调用。

有点绕口,我们不妨作如下实验来说明问题:

Main之前插入一个新脚本页,名字随便,而后写入如下代码:

module TestInclude
    def update
    p "外部方法被调用"   #验证一下自己的方法是否被调用
    super
    end
end
class Game_Player
    include TestInclude
end

代码很简单也很好理解,定义一个名为TestInclude的模块,此模块内部含有一个update方法,之后我们将此模块include至Game_Player模块,这样一来,系统对Game_Player的update方法调用完毕之后将自动调用TestInclude里的update——也就是说,我们自己模块中的方法成为了系统自带的Game_Player模块中update方法的逻辑补充。

点F12执行,则带有“外部方法被调用”字样的对话框会弹出。由于系统对于Game_Player里的update是一直调用的,因此我们自己模块里的update也会一直向外弹对话框,从任务管理器里将Game.exe扼杀掉即可。

之前也看过神思大人写的战斗CP脚本系统,有很多新人反应不知道该怎样引入自己的工程。我想如果借助于这种方法,神思大人完全可以将自己的CP系统也改装成不依赖于原有系统脚本且随用随引的独立系统了。

至于官方注释中提到的多重继承,这是C++中一种稍复杂的机制,这里不再讨论。其实在本人看来,Mix-in更像是多重反向继承。大家细心的话,应该就可以发现,对于include的外部模块,系统是优先调用原模块的方法,而后调用include模块中的方法,与C++中继承机制的调用顺序相反。
            本帖来自P1论坛作者独孤残云,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=153809若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: 【新手互助】利用Mix-in(糅合)构建低耦合脚本