接着前面的文章。
前言
cocos2d-js
的入侵再试先停一停。
通过前面的入侵,虽然还是很肤浅的,但是了解了一些插件系统的基本套路。
那么接下来自然就想要试一下让 creator
自己入侵自己了。
入侵
初步的需求和以前一样,在插件的 Panel
加载运行一个 Creator
的项目就可以了。
这个需要求有点像 Creator
中的 运行预览
功能,只是我们需要在插件中加载的是另一个 Creator
项目。
有了前面的经验,我们就可以直接开干了。
首先新建一个,HelloWorld
项目,直接在网页中运行起来,然后查看一下 DOM
树,然后可以看到熟悉的部分:
<div id="content" class="content">
<div class="contentWrap">
<div id="GameDiv" class="wrapper">
<canvas id="GameCanvas"></canvas>
</div>
</div>
</div>
和 cocos2d-js
几乎一样,Creator
也是通过一个 GameCanvas
来渲染游戏的。
那么我们就来试试,能不能把我们的 HelloWorld
项目的内容,渲染到插件中。
我们的 HelloWorld
发布后的目录是:
web-desktop/
assets/
cocos2d-js.js
index.html
main.js
src/settings.js
style-desktop.css
我们把其中的一些文见内容整合到插件中:
index.html
这个只需要 canvas
Editor.Panel.extend({
template: `
<div id="GameDiv" class="wrapper">
<canvas id="GameCanvas"></canvas>
</div>
`
});
然后是 css
Editor.Panel.extend({
style: Fs.readFileSync(Editor.url(".../style-desktop.css", "utf8"))
});
然后是 index.html
中的启动脚本:
Editor.Panel.extend({
ready() {
function loadScript(moduleName, cb) {
function scriptLoaded() {
document.body.removeChild(domScript);
domScript.removeEventListener('load', scriptLoaded, false);
cb && cb();
};
var domScript = document.createElement('script');
domScript.async = true;
domScript.src = moduleName;
domScript.addEventListener('load', scriptLoaded, false);
document.body.appendChild(domScript);
}
loadScript(Editor.url(".../cocos2d-js.js", "utf8"), function() {
window.boot();
});
}
});
直接运行,尝试一下,让然会报错。
首先遇到的问题是,之前也碰到过的:
// cocos2d-js.js. _initRenderer
var element = document.getElementById("creator2d-plugin-dev").shadowRoot.getElementById("GameDiv");
需要通过 shadowRoot
来获取 Canvas
。
再次运行,还是会有很多报错:
// net::ERR_FILE_NOT_FOUND
.../CocosCreator.app/Contents/Resources/static/assets/internal/config.json
.../CocosCreator.app/Contents/Resources/static/assets/internal/index.js
.../CocosCreator.app/Contents/Resources/static/assets/main/config.json
.../CocosCreator.app/Contents/Resources/static/assets/main/index.js
都是文件没有加载到的错误。
实际找一下,确实在上述路径下不存在,但是这些文件在发布文件夹 web-desktop
下都是存在的。
可以想见,是因为处于插件的环境之下,加载路径需要做一些修改。
通过代码调试,找到了源头在 main.js/window.boot
中:
let bundleRoot = [INTERNAL, MAIN];
settings.hasStartSceneBundle && bundleRoot.push(START_SCENE);
settings.hasResourcesBundle && bundleRoot.push(RESOURCES);
for (let i = 0; i < bundleRoot.length; i++) {
cc.assetManager.loadBundle(bundleRoot[i], cb);
}
然后出现问题的地方,在 cocos2d-js.js
中 :
var downloadBundle = function downloadBundle(nameOrUrl, options, onComplete) {
var bundleName = cc.path.basename(nameOrUrl);
var url = nameOrUrl;
REGEX.test(url) || (url = "assets/" + bundleName);
// ...
var config = url + "/config." + (version ? version + "." : "") + "json";
downloadJson(config, options, (function(err, response) {
// ...
}));
var js = url + "/index." + (version ? version + "." : "") + "js";
downloadScript(js, options, (function(err) {
// ...
}));
}
既然找到了地方,就先用不讲究的方法,来证实一下:
url = ".../web-desktop/assets/" + bundleName;
然后运行,可以看到这次没有问题了:
再来验证一下,运行一下官方自带的一个游戏实例 [tutorial-first-game](https://github.com/cocos-creator/tutorial-first-game)
同样的发布,修改一些代码,然后拷贝到我们的插件中刷新面板:
实验很成功,可以正常的运行,并且可以通过键盘进行操控。
最后再来试试随便拖一些控件:
也很成功。
其实有了前面的经验,把发布后的 Creator
整合到插件还是比较顺利的。
但是和上一篇提到的一样,想要比较有实用价值的话,那么肯定希望是不需要发布后继承,而是可以随时的在插件中加载另一个正在开发的 Creator
项目。
这里做了简单的尝试,但是难度比想象之要大,主要是 Creator
调试预览项目不像 cocos2d-js
那么单纯,似乎在点击 项目运行预览
后,实际还做了一些操作( quick-compile
),暂时还在研究中 …