[就问你6不6] creator 入侵 Creator 插件系统 - 5

接着前面的文章

前言

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 ),暂时还在研究中 …

4赞

GIF 有点糊了呀

昵称和头像不是很搭。

好东西啊, 这样真的简化了插件开发需求的技术。只要会creator,开发游戏和插件都可以了,感觉在3.0中可以出个构建插件的扩展,感觉最好官方来做下,解决下存在的一些问题。

mark!!!

只是简化了视图方面的操作,但如果熟悉vue,操作起来比用cocos制作插件面板会更快,但这确实降低了插件开发门槛

最近在集成一个独立的html页面到插件系统,本文相当有参考价值。