项目配置
大厅一个工程,子游戏一个工程。
子游戏工程所有资源都放在一个目录下,例如SubGame。选择这个目录,设置为Bundle。
大厅工程下我放入了这个插件ccc-devtools,在preview-template里面放入两个文件,一个import-map.json,这里面填子游戏的配置信息;一个bundle.js,主要解决找不到rollupPluginModLoBabelHelpers.js脚本的问题。
import-map.json
{
"imports": {
"virtual:///prerequisite-imports/SubGame": "chunks:///_virtual/SubGame"
}
}
bundle.js
System.register([], function(_export, _context) { return { execute: function () {
System.register("chunks:///_virtual/rollupPluginModLoBabelHelpers.js",[],(function(e){"use strict";return{execute:function(){function i(t,r){return(i=e("setPrototypeOf",Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,i){return e.__proto__=i,e}))(t,r)}e({applyDecoratedDescriptor:function(e,i,t,r,n){var o={};Object.keys(r).forEach((function(e){o[e]=r[e]})),o.enumerable=!!o.enumerable,o.configurable=!!o.configurable,("value"in o||o.initializer)&&(o.writable=!0);o=t.slice().reverse().reduce((function(t,r){return r(e,i,t)||t}),o),n&&void 0!==o.initializer&&(o.value=o.initializer?o.initializer.call(n):void 0,o.initializer=void 0);void 0===o.initializer&&(Object.defineProperty(e,i,o),o=null);return o},assertThisInitialized:function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e},inheritsLoose:function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,i(e,t)},initializerDefineProperty:function(e,i,t,r){if(!t)return;Object.defineProperty(e,i,{enumerable:t.enumerable,configurable:t.configurable,writable:t.writable,value:t.initializer?t.initializer.call(r):void 0})},setPrototypeOf:i})}}}));
} }; });
在index.ejs中添加两行代码。
<html>
....
<script src="import-map.json" type="systemjs-importmap" charset="utf-8"> </script>
<script src="bundle.js" charset="utf-8"> </script>
</html>
大厅里面加载子游戏场景代码
assetManager.loadBundle('http://192.168.3.75:9988/SubGame', {version: '7d58b'}, (err, bundle) => {
bundle.loadScene('scene', (err: Error, scene: SceneAsset) => {
console.log(scene);
director.runScene(scene);
});
});
因为子游戏打包有用到MD5,所以每次子游戏更新后上面的version值要自己改下。
解决跨域,nginx的配置如下:
server {
listen 9988;
server_name somename alias another.alias;
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
root D:/CocosCreator/SubGameTest_1/build/web-desktop/assets;
index index.html index.htm;
}
}
经过上面调整,只用打包子游戏工程,不用去打包大厅的工程。
如果要打包发布,在大厅工程下需要建立一个对应子游戏的空目录,例如上面的SubGame,将这个目录设置为bundle,这样,不用去打包出来的import-map.json里面手动添加上面import-map.json里面的内容。
公共脚本
建立个Common文件夹,将公共脚本都放里面,每个项目都有一样内容的Common文件夹。在所有项目中将这个文件夹设为Bundle。任意选一个项目打包一次,获得这个Common文件夹的Bundle,然后放到服务器上。
修改大厅项目的import-map.json为:
{
"imports": {
"virtual:///prerequisite-imports/Common": "chunks:///_virtual/Common",
"virtual:///prerequisite-imports/SubGame": "chunks:///_virtual/SubGame"
}
}
在合适的位置加载公共脚本:
assetManager.loadBundle('http://192.168.3.75:9988/Common', {version: '986d4'}, (err, bundle) => {
console.log(bundle);
});
目前这种方法加载会报错:debug.ts:103 A Class already exists with the same cid。暂时还不知道怎么处理。这种报错目前发现不影响游戏逻辑,先放着不管了。发布正式包是不会有这种报错。
全局变量
有些数据需要共享,这里建立Global.ts脚本用来放全局共享的数据。
大厅Global.ts
export class Global {
public static data: IData;
}
// 注册到全局环境中
window['Global'] = window['Global'] || Global;
子游戏Global.ts
interface Global {
data: IData;
}
let Global: Global = window['Global'];
export {Global};
其中IData只是接口,用来暴露数据类型,为了方便在子游戏工程中有更好的代码提示。
注意
- 对应平台只能加载对应平台打出来的bundle。比如大厅是Android平台,子游戏打包需要创建个Android Build Task,这样构建出的Bundle才能正确的被大厅加载。