Project1
标题:
RPG Maker MV 的源码研究 其二
[打印本页]
作者:
沉滞的剑
时间:
2019-8-11 07:59
标题:
RPG Maker MV 的源码研究 其二
研究源码需要一些额外的辅助手段
因为代码并不是从上一直写到下的
而是跳跃的, 所以必须要有一个工具帮你做一些全局搜索
推荐使用Visual Studio Code来作为你的编辑器
它强大, 颜值高, 易拓展, 你值得拥有.
==================================
第一章 插件管理者: 就算突破常规, 尔等仍为我掌控
在入口文件真正执行SceneManager.run(Scene_Boot)开启我们的游戏循环之前
还执行了PluginManager.setup($plugins)
先说说PluginManager
PluginManager和其他Manager一样是一个静态类
说白了就是个全局变量
不过在MV里面, 全部都是以 function xxxManager() {} 的方法声明的
实际上这些PluginManager完全没有用到function的功能,
所以只需要写const PluginManager = {} 就可以了
接下来PluginManager定义了四个内部变量
PluginManager._path = 'js/plugins/';
PluginManager._scripts = [];
PluginManager._errorUrls = [];
PluginManager._parameters = {};
复制代码
先不去管他, 等到具体使用时候再分析
这里可以直接初始化为 const PluginManager = {_path: 'js/plugins/'...}就可以了
接下来我们看下它的方法:
PluginManager.setup
PluginManager.checkErrors
PluginManager.parameters
PluginManager.setParameters
PluginManager.loadScript
PluginManager.onError
复制代码
首先setup方法用来加载插件配置
插件配$plugins是在plugin.js里定义的
我们通过工具内的插件管理器可以对这个文件进行修改
然后我们来看这个方法内部
PluginManager.setup = function (plugins) {
plugins.forEach(function (plugin) {
if (plugin.status && !this._scripts.contains(plugin.name)) {
this.setParameters(plugin.name, plugin.parameters);
this.loadScript(plugin.name + '.js');
this._scripts.push(plugin.name);
}
}, this);
};
复制代码
forEach是一个高阶函数, 它的作用类似for循环
具体使用方法参考: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
这段代码翻译为自然语言就是:
对于plugins里的每一个plugin:
我们判断它是否是开启状态并且还未被加载过, 如果是则继续, 否则跳过这个plugin
我们调用setParameters来记录plugin的参数
我们将plugin指向的脚本加载到网页中
我们标记这个plugin已经被加载过了
复制代码
下面我们将继续研究setParameters和loadScript方法
PluginManager.parameters = function (name) {
return this._parameters[name.toLowerCase()] || {};
};
PluginManager.setParameters = function (name, parameters) {
this._parameters[name.toLowerCase()] = parameters;
};
复制代码
这两个方法可以放到一起说, 其实不难看出这两个方法只是_parameters的setter和getter了
由于PluginManager是一个全局对象, 所以插件里的配置其实是可以动态读取甚至修改的
我们也是通过这种方法读取插件里parameters的配置的
继续看加载放啊loadScript
PluginManager.loadScript = function (name) {
var url = this._path + name;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
script.async = false;
script.onerror = this.onError.bind(this);
script._url = url;
document.body.appendChild(script);
};
复制代码
这句话是做什么的呢?
我们知道网页加载js文件是通过js标签来实现的
例如
<script type='text/javascript' src='./app.js'>
复制代码
而js代码又可以通过appendChild为html代码添加标签于是这段代码的本质就是在网页的body里的最下面添加一个新的script标签
比如初始工程运行时, 你打开F12, 会在element里面看到当前的网页结构
你会发现和我们的index.html并不完全一样
比如在
<script type="text/javascript" src="js/main.js"></script>
复制代码
下面就会多出来
<script type="text/javascript" src="js/plugins/Community_Basic.js"></script>
<script type="text/javascript" src="js/plugins/MadeWithMv.js"></script>
复制代码
实际上这两个标签就是loadScript方法添加的
但这里面还有两个需要说明的
script.async = false;
这个代表脚本不是异步加载的, 这样只有这个脚本加载完毕后面的代码才会继续执行
同步/异步在js世界里是一个很需要关注的地方
尤其是加载外部资源的时候
script.onerror = this.onError.bind(this);
这个是添加了一个错误handler
如plugin的脚本出错了, 就会将这个错误记录下去
在SceneManager执行初始化检查的时候
如果有错误就会展示一个错误界面给大家看
如果经常使用plugin的制作者肯定很熟悉那个画面啦
这样最简单的manager, PluginManager我就水完了~
作者:
antilmid
时间:
2019-8-11 09:05
你尝试去把里面的生命周期整理一下,会很有帮助
作者:
walf_man
时间:
2019-8-12 11:46
不错,学习到了很多的知识
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1