zhaochengyang 5 年 前
コミット
f91ab39010
83 ファイル変更169499 行追加0 行削除
  1. 58 0
      .laya/compile.js
  2. 43 0
      .laya/launch.json
  3. 429 0
      .laya/publish.js
  4. 446 0
      .laya/publish_oppogame.js
  5. 726 0
      .laya/publish_vivogame.js
  6. 518 0
      .laya/publish_xmgame.js
  7. 1 0
      DateTheGirl.laya
  8. BIN
      bin/Resources/-10.png
  9. BIN
      bin/Resources/-11.png
  10. BIN
      bin/Resources/-7.png
  11. BIN
      bin/Resources/-9.png
  12. BIN
      bin/Resources/1.png
  13. BIN
      bin/Resources/2.png
  14. BIN
      bin/Resources/3.png
  15. BIN
      bin/Resources/4.png
  16. BIN
      bin/Resources/5.png
  17. BIN
      bin/Resources/6.png
  18. BIN
      bin/Resources/BG.png
  19. 1 0
      bin/fileconfig.json
  20. 32 0
      bin/index.html
  21. 15 0
      bin/index.js
  22. 3746 0
      bin/libs/bytebuffer.js
  23. 2357 0
      bin/libs/domparserinone.js
  24. 4212 0
      bin/libs/laya.ani.js
  25. 1682 0
      bin/libs/laya.bdmini.js
  26. 25646 0
      bin/libs/laya.core.js
  27. 31335 0
      bin/libs/laya.d3.js
  28. 9815 0
      bin/libs/laya.debugtool.js
  29. 653 0
      bin/libs/laya.device.js
  30. 1528 0
      bin/libs/laya.html.js
  31. 633 0
      bin/libs/laya.particle.js
  32. 2037 0
      bin/libs/laya.pathfinding.js
  33. 3196 0
      bin/libs/laya.physics.js
  34. 691 0
      bin/libs/laya.physics3D.js
  35. 380 0
      bin/libs/laya.physics3D.runtime.js
  36. 646 0
      bin/libs/laya.physics3D.wasm.js
  37. 1690 0
      bin/libs/laya.qqmini.js
  38. 1668 0
      bin/libs/laya.quickgamemini.js
  39. 1604 0
      bin/libs/laya.tiledmap.js
  40. 6069 0
      bin/libs/laya.ui.js
  41. 1673 0
      bin/libs/laya.vvmini.js
  42. 1689 0
      bin/libs/laya.wxmini.js
  43. 1677 0
      bin/libs/laya.xmmini.js
  44. 1 0
      bin/libs/worker.js
  45. 132 0
      bin/libs/workerloader.js
  46. 40 0
      bin/res/atlas/.rec
  47. 1 0
      bin/res/atlas/comp.atlas
  48. BIN
      bin/res/atlas/comp.png
  49. 1 0
      bin/version.json
  50. 53 0
      laya/.laya
  51. BIN
      laya/assets/game/-10.png
  52. BIN
      laya/assets/game/-11.png
  53. BIN
      laya/assets/game/-7.png
  54. BIN
      laya/assets/game/-9.png
  55. BIN
      laya/assets/game/1.png
  56. BIN
      laya/assets/game/2.png
  57. BIN
      laya/assets/game/3.png
  58. BIN
      laya/assets/game/4.png
  59. BIN
      laya/assets/game/5.png
  60. BIN
      laya/assets/game/6.png
  61. BIN
      laya/assets/game/bg.png
  62. 1 0
      laya/ignore.cfg
  63. 318 0
      laya/pages/Main1.scene
  64. 1 0
      laya/pages/Prefab_Ball/ball1.prefab
  65. 1 0
      laya/pages/Prefab_Ball/ball2.prefab
  66. 1 0
      laya/pages/Prefab_Ball/ball3.prefab
  67. 1 0
      laya/pages/Prefab_Ball/ball4.prefab
  68. 1 0
      laya/pages/Prefab_Ball/ball5.prefab
  69. 1 0
      laya/pages/Prefab_Ball/ball6.prefab
  70. 49305 0
      libs/LayaAir.d.ts
  71. 484 0
      libs/layaAir.minigame.d.ts
  72. 6118 0
      libs/union.d.ts
  73. 5639 0
      libs/wx.d.ts
  74. 3 0
      src/Game/AssetManager.ts
  75. 14 0
      src/Game/Ball.ts
  76. 38 0
      src/Game/BallControl.ts
  77. 5 0
      src/Game/LoadAsset.ts
  78. 25 0
      src/GameConfig.ts
  79. 37 0
      src/Main.ts
  80. 56 0
      src/Tool/Dictionary.ts
  81. 64 0
      src/Tool/GamePool.ts
  82. 251 0
      src/Tool/GameTool.ts
  83. 11 0
      tsconfig.json

+ 58 - 0
.laya/compile.js

@@ -0,0 +1,58 @@
+// v1.1.0
+//是否使用IDE自带的node环境和插件,设置false后,则使用自己环境(使用命令行方式执行)
+let useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false;
+//获取Node插件和工作路径
+let ideModuleDir = useIDENode ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : "";
+let workSpaceDir = useIDENode ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\compile.js", "").replace("/.laya/compile.js", "") : "./../";
+
+const gulp = require(ideModuleDir + "gulp");
+const rollup = require(ideModuleDir + "rollup");
+const typescript = require(ideModuleDir + 'rollup-plugin-typescript2');//typescript2 plugin
+const glsl = require(ideModuleDir + 'rollup-plugin-glsl');
+
+// 如果是发布时调用编译功能,增加prevTasks
+let prevTasks = "";
+if (global.publish) {
+	prevTasks = ["loadConfig"];
+}
+
+//使用browserify,转换ts到js,并输出到bin/js目录
+gulp.task("compile", prevTasks, function () {
+	// 发布时调用编译功能,判断是否点击了编译选项
+	if (global.publish && !global.config.compile) {
+		return;
+	} else if (global.publish && global.config.compile) {
+		// 发布时调用编译,workSpaceDir使用publish.js里的变量
+		workSpaceDir = global.workSpaceDir;
+	}
+
+	return rollup.rollup({
+		input: workSpaceDir + '/src/Main.ts',
+		treeshake: true,//建议忽略
+		plugins: [
+			typescript({
+				check: false, //Set to false to avoid doing any diagnostic checks on the code
+				tsconfigOverride:{compilerOptions:{removeComments: true}}
+			}),
+			glsl({
+				// By default, everything gets included
+				include: /.*(.glsl|.vs|.fs)$/,
+				sourceMap: false,
+				compress:false
+			}),
+			/*terser({
+				output: {
+				},
+				numWorkers:1,//Amount of workers to spawn. Defaults to the number of CPUs minus 1
+				sourcemap: false
+			})*/        
+		]
+	}).then(bundle => {
+		return bundle.write({
+			file: workSpaceDir + '/bin/js/bundle.js',
+			format: 'iife',
+			name: 'laya',
+			sourcemap: false
+		});
+	});
+});

+ 43 - 0
.laya/launch.json

@@ -0,0 +1,43 @@
+{
+	"version": "0.2.0",
+	"configurations": [ 
+		{
+			"name": "layaAir",
+			"type": "chrome",
+			"request": "launch",
+			"file": "${workspaceRoot}/bin/index.html",
+			"runtimeExecutable": "${execPath}",
+			"useBuildInServer": true,
+			"sourceMaps": true,
+			"webRoot": "${workspaceRoot}",
+			"port": 9222,
+			"fixedPort":false,
+			"sourceMapPathOverrides": {
+				"src/*": "${workspaceRoot}/src/*"
+			}		
+		},
+		{
+			"name": "chrome调试",
+			"type": "chrome",
+			"request": "launch",
+			"file": "${workspaceRoot}/bin/index.html",
+			// "换成自己的谷歌安装路径,": 比如
+			//window 默认安装路径为: "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
+			//mac 系统上的默认安装路径为 "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
+			// "runtimeExecutable": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
+			"runtimeArgs": [
+				"--allow-file-access-from-files",
+				"--allow-file-access-frome-files",
+				" --disable-web-security"
+			],
+			"sourceMaps": true,
+			"webRoot": "${workspaceRoot}",
+			//假如谷歌调试报userDataDir不可用,请把谷歌安装路径取得管理员权限,或者更换${tmpdir}为其他可以读写的文件夹,也可以删除。
+			"userDataDir": "${workspaceRoot}/.laya/chrome",
+			"fixedPort":false,
+			"sourceMapPathOverrides": {
+				"src/*": "${workspaceRoot}/src/*"
+			}		
+		}
+	]
+}

+ 429 - 0
.laya/publish.js

@@ -0,0 +1,429 @@
+// v1.4.0
+//是否使用IDE自带的node环境和插件,设置false后,则使用自己环境(使用命令行方式执行)
+const useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false;
+//获取Node插件和工作路径
+let ideModuleDir = useIDENode ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : "";
+let workSpaceDir = useIDENode ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\publish.js", "").replace("/.laya/publish.js", "") + "/" : "./../";
+
+//引用插件模块
+const gulp = require(ideModuleDir + "gulp");
+const fs = require("fs");
+const path = require("path");
+const uglify = require(ideModuleDir + 'gulp-uglify-es').default;
+const jsonminify = require(ideModuleDir + "gulp-jsonminify");
+const image = require(ideModuleDir + "gulp-image");
+const rev = require(ideModuleDir + "gulp-rev");
+const revdel = require(ideModuleDir + "gulp-rev-delete-original");
+const revCollector = require(ideModuleDir + 'gulp-rev-collector');
+const del = require(ideModuleDir + "del");
+const requireDir = require(ideModuleDir + 'require-dir');
+
+global.ideModuleDir = ideModuleDir;
+global.workSpaceDir = workSpaceDir;
+
+// 结合compile.js使用
+global.publish = true;
+const fileList = ["compile.js", "publish_xmgame.js", "publish_oppogame.js", "publish_vivogame.js"];
+requireDir('./', {
+	filter: function (fullPath) {
+		// 只用到了compile.js和publish.js
+		if (fileList.includes(path.basename(fullPath))) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+});
+
+const QUICKGAMELIST = ["xmgame", "oppogame", "vivogame"];
+
+// 清理临时文件夹,加载配置
+let config,
+	releaseDir,
+	binPath,
+	platform,
+	isOpendataProj = false;
+gulp.task("loadConfig", function () {
+	platform = "web"
+	if (!useIDENode && process.argv.length > 5 && process.argv[4] == "--config") {
+		platform = process.argv[5].replace(".json", "");
+	}
+	if (useIDENode && process.argv.length >= 4 && process.argv[3].startsWith("--config") && process.argv[3].endsWith(".json")) {
+		platform = process.argv[3].match(/(\w+).json/)[1];
+	}
+	let _path;
+	if (!useIDENode) {
+		_path = platform + ".json";
+		releaseDir = "../release/" + platform;
+		binPath = "../bin/";
+	}
+	if (useIDENode) {
+		_path = path.join(workSpaceDir, ".laya", `${platform}.json`);
+		releaseDir = path.join(workSpaceDir, "release", platform).replace(/\\/g, "/");
+		binPath = path.join(workSpaceDir, "bin").replace(/\\/g, "/");
+	}
+	global.platform = platform;
+	let file = fs.readFileSync(_path, "utf-8");
+	if (file) {
+		if (QUICKGAMELIST.includes(platform)) {
+			file = file.replace(/\$basePath/g, releaseDir + "/temprelease");
+		} else {
+			file = file.replace(/\$basePath/g, releaseDir);
+		}
+		config = JSON.parse(file);
+		global.config = config;
+	}
+	// 是否是开放域项目
+	let projInfoPath = path.join(workSpaceDir, path.basename(workSpaceDir) + ".laya");
+	let isExist = fs.existsSync(projInfoPath);
+	if (isExist) {
+		try {
+			let projInfo = fs.readFileSync(projInfoPath, "utf8");
+			projInfo = projInfo && JSON.parse(projInfo);
+			isOpendataProj = projInfo.layaProType === 12;
+		} catch (e) {}
+	}
+});
+
+// 重新编译项目
+// gulp.task("compile", ["loadConfig"], function () {
+// 	if (config.compile) {
+// 		console.log("compile");
+// 	}
+// });
+
+// 清理release文件夹
+gulp.task("clearReleaseDir", ["compile"], function (cb) {
+	if (config.clearReleaseDir) {
+		let delList = [releaseDir, releaseDir + "_pack", config.packfileTargetValue];
+		// 小米快游戏,使用即存的项目,删掉Laya工程文件,保留小米环境项目文件
+		if (platform === "xmgame") {
+			let xmProjSrc = path.join(releaseDir, config.xmInfo.projName);
+			// 不要删掉manifest.json/main.js文件
+			// 这里不是node-glob语法,详见: https://github.com/sindresorhus/del
+			delList = [`${xmProjSrc}/**`, `!${xmProjSrc}`, `!${xmProjSrc}/node_modules/**`, `!${xmProjSrc}/sign/**`, `!${xmProjSrc}/{babel.config.js,main.js,manifest.json,package.json,package-lock.json}`];
+		} else if (platform === "oppogame") {
+			let oppoProjSrc = path.join(releaseDir, config.oppoInfo.projName);
+			delList = [`${oppoProjSrc}/**`, `!${oppoProjSrc}`, `!${oppoProjSrc}/dist/**`, `!${oppoProjSrc}/{manifest.json}`];
+		} else if (platform === "vivogame") {
+			let vvProj = path.join(releaseDir, config.vivoInfo.projName);
+			let vvProjSrc = path.join(vvProj, "src");
+			// 不要删掉manifest.json/main.js文件
+			// 这里不是node-glob语法,详见: https://github.com/sindresorhus/del
+			delList = [`${vvProjSrc}/**`, `!${vvProjSrc}`, `!${vvProjSrc}/sign/**`, `!${vvProjSrc}/{game.js,manifest.json}`];
+			delList = delList.concat(`${vvProj}/engine/**`, `${vvProj}/config/**`);
+		}
+		del(delList, { force: true }).then(paths => {
+			cb();
+		});
+	} else cb();
+});
+
+// copy bin文件到release文件夹
+gulp.task("copyFile", ["clearReleaseDir"], function () {
+	let baseCopyFilter = [`${workSpaceDir}/bin/**/*.*`, `!${workSpaceDir}/bin/indexmodule.html`, `!${workSpaceDir}/bin/import/*.*`];
+	// 只拷贝index.js中引用的类库
+	if (config.onlyIndexJS) {
+		baseCopyFilter = baseCopyFilter.concat(`!${workSpaceDir}/bin/libs/*.*`);
+	}
+	if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,仅拷贝用到的文件
+		config.copyFilesFilter = [`${workSpaceDir}/bin/js/bundle.js`, `${workSpaceDir}/bin/index.js`, `${workSpaceDir}/bin/game.js`];
+		if (config.projectType !== "as") { // 开放域精简类库
+			config.copyFilesFilter.push(`${workSpaceDir}/bin/libs/laya.opendata.min.js`);
+		}
+	} else if (platform === "wxgame") { // 微信项目,不拷贝index.html,不拷贝百度bin目录中的文件
+		config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/index.html`, `!${workSpaceDir}/bin/{project.swan.json,swan-game-adapter.js}`]);
+	} else if (platform === "bdgame") { // 百度项目,不拷贝index.html,不拷贝微信bin目录中的文件
+		config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/index.html`, `!${workSpaceDir}/bin/{project.config.json,weapp-adapter.js}`]);
+	} else { // web|QQ项目|bili|快游戏,不拷贝微信、百度在bin目录中的文件
+		config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{game.js,game.json,project.config.json,weapp-adapter.js,project.swan.json,swan-game-adapter.js}`]);
+	}
+	// bili/alipay/qq,不拷贝index.html
+	if (["biligame", "Alipaygame", "qqgame"].includes(platform)) {
+		config.copyFilesFilter = config.copyFilesFilter.concat([`!${workSpaceDir}/bin/index.html`]);
+	}
+	// 快游戏,需要新建一个快游戏项目,拷贝的只是项目的一部分,将文件先拷贝到文件夹的临时目录中去
+	if (QUICKGAMELIST.includes(platform)) {
+		config.copyFilesFilter = config.copyFilesFilter.concat([`!${workSpaceDir}/bin/index.html`]);
+		releaseDir = global.tempReleaseDir = path.join(releaseDir, "temprelease");
+	}
+	if (config.exclude) { // 排除文件
+		config.excludeFilter.forEach(function(item, index, list) {
+			releaseDir = releaseDir.replace(/\\/g, "/");
+			config.excludeFilter[index] = item.replace(releaseDir, binPath);
+		});
+		config.copyFilesFilter = config.copyFilesFilter.concat(config.excludeFilter);
+	}
+	global.releaseDir = releaseDir;
+	var stream = gulp.src(config.copyFilesFilter, { base: `${workSpaceDir}/bin` });
+	return stream.pipe(gulp.dest(releaseDir));
+});
+
+// copy libs中的js文件到release文件夹
+gulp.task("copyLibsJsFile", ["copyFile"], function () {
+	if (!config.onlyIndexJS) {
+		return;
+	}
+	if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,拷贝文件时已经拷贝类库文件了
+		return;
+	}
+	// 开放域项目,as语言,没有libs目录,mac系统报错
+	let libs = path.join(workSpaceDir, "bin", "libs");
+	if (!fs.existsSync(libs)) {
+		return;
+	}
+	// 分析index.js
+	let indexJSPath = path.join(workSpaceDir, "bin", "index.js");
+	let indexJsContent = fs.readFileSync(indexJSPath, "utf8");
+	let libsList = indexJsContent.match(/loadLib\(['"]libs\/[\w-./]+\.(js|wasm)['"]\)/g);
+	if (!libsList) {
+		libsList = [];
+	}
+	let 
+		item,
+		libsName = "",
+		libsStr = "";
+	for (let i = 0, len = libsList.length; i < len; i++) {
+		item = libsList[i];
+		libsName = item.match(/loadLib\(['"]libs\/([\w-./]+\.(js|wasm))['"]\)/);
+		libsStr += libsStr ? `,${libsName[1]}` : libsName[1];
+	}
+	let copyLibsList = [`${workSpaceDir}/bin/libs/{${libsStr}}`];
+	if (!libsStr.includes(",")) {
+		copyLibsList = [`${workSpaceDir}/bin/libs/${libsStr}`];
+	}
+	// 微信、百度,需要拷贝对应平台的类库
+	if (platform === "wxgame") {
+		copyLibsList.push(`${workSpaceDir}/bin/libs/laya.wxmini.js`);
+	} else if (platform === "bdgame") {
+		copyLibsList.push(`${workSpaceDir}/bin/libs/laya.bdmini.js`);
+	} else if (platform === "qqgame") {
+		copyLibsList.push(`${workSpaceDir}/bin/libs/laya.qqmini.js`);
+	}
+	var stream = gulp.src(copyLibsList, { base: `${workSpaceDir}/bin` });
+	return stream.pipe(gulp.dest(releaseDir));
+});
+
+// 根据不同的项目类型拷贝平台文件
+gulp.task("copyPlatformFile", ["copyLibsJsFile"], function () {
+	let fileLibsPath;
+	if (useIDENode) {
+		fileLibsPath = path.join(ideModuleDir, "../", "out", "layarepublic", "LayaAirProjectPack", "lib", "data");
+	} else if (process.argv.length >= 8 && process.argv[6] === "--libspath") {
+		fileLibsPath = process.argv[7];
+		console.log("平台文件包是否存在: " + fs.existsSync(fileLibsPath));
+	} else {
+		console.log("没有接收到可用文件包位置,不拷贝对应平台文件");
+		return;
+	}
+	// 开放域项目,微信发布
+	if (platform === "wxgame" && isOpendataProj) {
+		let platformDir = path.join(fileLibsPath, "wxfiles", "weapp-adapter.js");
+		let stream = gulp.src(platformDir);
+		return stream.pipe(gulp.dest(releaseDir));
+	}
+	// 微信项目,非开放域项目
+	if (platform === "wxgame") {
+		// 如果新建项目时已经点击了"微信/百度小游戏bin目录快速调试",不再拷贝
+		let isHadWXFiles =
+			fs.existsSync(path.join(workSpaceDir, "bin", "game.js")) &&
+			fs.existsSync(path.join(workSpaceDir, "bin", "game.json")) &&
+			fs.existsSync(path.join(workSpaceDir, "bin", "project.config.json")) &&
+			fs.existsSync(path.join(workSpaceDir, "bin", "weapp-adapter.js"));
+		if (isHadWXFiles) {
+			return;
+		}
+		let platformDir = path.join(fileLibsPath, "wxfiles");
+		let stream = gulp.src(platformDir + "/*.*");
+		return stream.pipe(gulp.dest(releaseDir));
+	}
+	// 百度项目
+	if (platform === "bdgame") {
+		// 如果新建项目时已经点击了"微信/百度小游戏bin目录快速调试",不再拷贝
+		let isHadBdFiles =
+			fs.existsSync(path.join(workSpaceDir, "bin", "game.js")) &&
+			fs.existsSync(path.join(workSpaceDir, "bin", "game.json")) &&
+			fs.existsSync(path.join(workSpaceDir, "bin", "project.swan.json")) &&
+			fs.existsSync(path.join(workSpaceDir, "bin", "swan-game-adapter.js"));
+		if (isHadBdFiles) {
+			return;
+		}
+		let platformDir = path.join(fileLibsPath, "bdfiles");
+		let stream = gulp.src(platformDir + "/*.*");
+		return stream.pipe(gulp.dest(releaseDir));
+	}
+	// QQ小游戏
+	if (platform === "qqgame") {
+		let platformDir = path.join(fileLibsPath, "qqfiles");
+		let stream = gulp.src(platformDir + "/*.*");
+		return stream.pipe(gulp.dest(releaseDir));
+	}
+});
+
+// 拷贝文件后,针对特定平台修改文件内容
+gulp.task("modifyFile", ["copyPlatformFile"], function () {
+	// QQ小游戏
+	// if (platform === "qqgame") {
+	// 	return;
+	// }
+
+	// 百度项目,修改index.js
+	if (platform === "bdgame") {
+		let filePath = path.join(releaseDir, "index.js");
+		if (!fs.existsSync(filePath)) {
+			return;
+		}
+		let fileContent = fs.readFileSync(filePath, "utf8");
+		fileContent = fileContent.replace(/loadLib\(/g, "require(");
+		fs.writeFileSync(filePath, fileContent, "utf8");
+		return;
+	}
+});
+
+// 压缩json
+gulp.task("compressJson", ["modifyFile"], function () {
+	if (config.compressJson) {
+		return gulp.src(config.compressJsonFilter, { base: releaseDir })
+			.pipe(jsonminify())
+			.pipe(gulp.dest(releaseDir));
+	}
+});
+
+// 压缩js
+gulp.task("compressJs", ["compressJson"], function () {
+	if (config.compressJs) {
+		return gulp.src(config.compressJsFilter, { base: releaseDir })
+			.pipe(uglify({
+				mangle: false
+			}))
+			.on('error', function (err) {
+				console.warn(err.toString());
+			})
+			.pipe(gulp.dest(releaseDir));
+	}
+});
+
+// 压缩png,jpg
+gulp.task("compressImage", ["compressJs"], function () {
+	if (config.compressImage) {
+		return gulp.src(config.compressImageFilter, { base: releaseDir })
+			.pipe(image({
+				pngquant: true,			//PNG优化工具
+				optipng: false,			//PNG优化工具
+				zopflipng: true,		//PNG优化工具
+				jpegRecompress: false,	//jpg优化工具
+				mozjpeg: true,			//jpg优化工具
+				guetzli: false,			//jpg优化工具
+				gifsicle: false,		//gif优化工具
+				svgo: false,			//SVG优化工具
+				concurrent: 10,			//并发线程数
+				quiet: true 			//是否是静默方式
+				// optipng: ['-i 1', '-strip all', '-fix', '-o7', '-force'],
+				// pngquant: ['--speed=1', '--force', 256],
+				// zopflipng: ['-y', '--lossy_8bit', '--lossy_transparent'],
+				// jpegRecompress: ['--strip', '--quality', 'medium', '--min', 40, '--max', 80],
+				// mozjpeg: ['-optimize', '-progressive'],
+				// guetzli: ['--quality', 85]
+			}))
+			.pipe(gulp.dest(releaseDir));
+	}
+});
+
+// 开放域的情况下,合并game.js和index.js,并删除game.js
+gulp.task("openData", ["compressImage"], function (cb) {
+	if (config.openDataZone) {
+		let indexPath = releaseDir + "/index.js";
+		let indexjs = readFile(indexPath);
+		let gamejs = readFile(releaseDir + "/game.js");
+		if (gamejs && indexjs) {
+			gamejs = gamejs.replace('require("index.js")', indexjs);
+			fs.writeFileSync(indexPath, gamejs, 'utf-8');
+		}
+		if (isOpendataProj) {
+			// 开放域项目,将game.js删掉,发布最小包
+			del(`${releaseDir}/game.js`, { force: true }).then(paths => {
+				cb();
+			}); 
+		} else {
+			cb();
+		}
+	} else {
+		cb();
+	}
+});
+
+function readFile(path) {
+	if (fs.existsSync(path)) {
+		return fs.readFileSync(path, "utf-8");
+	}
+	return null;
+}
+
+// 生成版本管理信息
+gulp.task("version1", ["openData"], function () {
+	if (config.version) {
+		return gulp.src(config.versionFilter, { base: releaseDir })
+			.pipe(rev())
+			.pipe(gulp.dest(releaseDir))
+			.pipe(revdel())
+			.pipe(rev.manifest("version.json"))
+			.pipe(gulp.dest(releaseDir));
+	}
+});
+
+// 替换index.js里面的变化的文件名
+gulp.task("version2", ["version1"], function () {
+	if (config.version) {
+		//替换index.html和index.js里面的文件名称
+
+		let htmlPath = releaseDir + "/index.html";
+		let versionPath = releaseDir + "/version.json";
+		let gameJSPath = releaseDir + "/game.js";
+		let mainJSPath = releaseDir + "/main.js";
+		let indexJSPath;
+		let versionCon = fs.readFileSync(versionPath, "utf8");
+		versionCon = JSON.parse(versionCon);
+		indexJSPath = releaseDir + "/" + versionCon["index.js"];
+		// 替换config.packfileFullValue中的路径
+		let packfileStr = JSON.stringify(config.packfileFullValue).replace(/\\\\/g, "/");
+		let tempPackfile = `${workSpaceDir}/.laya/configTemp.json`;
+		fs.writeFileSync(tempPackfile, packfileStr, "utf8");
+
+		let srcList = [versionPath, indexJSPath, tempPackfile];
+		if (fs.existsSync(htmlPath)) {
+			srcList.push(htmlPath);
+		}
+		if (fs.existsSync(gameJSPath)) {
+			srcList.push(gameJSPath);
+		}
+		if (fs.existsSync(mainJSPath)) {
+			srcList.push(mainJSPath);
+		}
+		return gulp.src(srcList)
+			.pipe(revCollector())
+			.pipe(gulp.dest(releaseDir));
+	}
+});
+
+// 筛选4M包
+gulp.task("packfile", ["version2"], function() {
+	if (config.version) {
+		// 从release目录取得带有版本号的目录
+		let tempPackfile = `${workSpaceDir}/.laya/configTemp.json`;
+		let releasePackfile = `${releaseDir}/configTemp.json`;
+		let packfileStr = fs.readFileSync(releasePackfile, "utf8");
+		config.packfileFullValue = JSON.parse(packfileStr);
+		// 删掉临时目录
+		fs.unlinkSync(tempPackfile);
+		fs.unlinkSync(releasePackfile);
+	}
+	if (config.packfile) { // 提取本地包(文件列表形式)
+		return gulp.src(config.packfileFullValue, { base: releaseDir })
+			.pipe(gulp.dest(config.packfileTargetValue || releaseDir + "_pack"));
+	}
+});
+
+// 起始任务
+gulp.task("publish", ["buildXiaomiProj", "buildOPPOProj", "buildVivoProj"], function () {
+	console.log("All tasks completed!");
+});

+ 446 - 0
.laya/publish_oppogame.js

@@ -0,0 +1,446 @@
+// v1.0.2
+// publish 2.x 也是用这个文件,需要做兼容
+let isPublish2 = process.argv[2].includes("publish_oppogame.js") && process.argv[3].includes("--evn=publish2");
+// 获取Node插件和工作路径
+let ideModuleDir, workSpaceDir;
+if (isPublish2) {
+	//是否使用IDE自带的node环境和插件,设置false后,则使用自己环境(使用命令行方式执行)
+	const useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false;
+	ideModuleDir = useIDENode ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : "";
+	workSpaceDir = useIDENode ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\publish_oppogame.js", "").replace("/.laya/publish_oppogame.js", "") + "/" : "./../";
+} else {
+	ideModuleDir = global.ideModuleDir;
+	workSpaceDir = global.workSpaceDir;
+}
+
+//引用插件模块
+const gulp = require(ideModuleDir + "gulp");
+const fs = require("fs");
+const path = require("path");
+const childProcess = require("child_process");
+const del = require(ideModuleDir + "del");
+const revCollector = require(ideModuleDir + 'gulp-rev-collector');
+let commandSuffix = ".cmd";
+
+let prevTasks = ["packfile"];
+if (isPublish2) {
+	prevTasks = "";
+}
+
+let 
+    config,
+	platform,
+	releaseDir,
+    toolkitPath,
+    tempReleaseDir, // OPPO临时拷贝目录
+	projDir; // OPPO快游戏工程目录
+let versionCon; // 版本管理version.json
+// 创建OPPO项目前,拷贝OPPO引擎库、修改index.js
+// 应该在publish中的,但是为了方便发布2.0及IDE 1.x,放在这里修改
+gulp.task("preCreate_OPPO", prevTasks, function() {
+	if (isPublish2) {
+		let pubsetPath = path.join(workSpaceDir, ".laya", "pubset.json");
+		let content = fs.readFileSync(pubsetPath, "utf8");
+		let pubsetJson = JSON.parse(content);
+		platform = "oppogame";
+		releaseDir = path.join(workSpaceDir, "release", platform).replace(/\\/g, "/");
+		releaseDir = tempReleaseDir = path.join(releaseDir, "temprelease");
+		config = pubsetJson[5]; // 只用到了 config.oppoInfo|config.oppoSign
+	} else {
+		platform = global.platform;
+		releaseDir = global.releaseDir;
+		tempReleaseDir = global.tempReleaseDir;
+		config = global.config;
+	}
+    toolkitPath = path.join(ideModuleDir, "../", "out", "layarepublic", "oppo", "quickgame-toolkit");
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	if (process.platform === "darwin") {
+		commandSuffix = "";
+	}
+	let copyLibsList = [`${workSpaceDir}/bin/libs/laya.quickgamemini.js`];
+	var stream = gulp.src(copyLibsList, { base: `${workSpaceDir}/bin` });
+	return stream.pipe(gulp.dest(tempReleaseDir));
+});
+
+// 新建OPPO项目-OPPO项目与其他项目不同,需要安装OPPO quickgame node_modules,并打包成.rpk文件
+gulp.task("installModules_OPPO", ["preCreate_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	releaseDir = path.dirname(releaseDir);
+	projDir = path.join(releaseDir, config.oppoInfo.projName);
+    // 如果IDE里对应OPPO包已经install node_modules了,忽略这一步
+    if (fs.existsSync(path.join(toolkitPath, "node_modules"))) {
+        return;
+    }
+	// 安装OPPO quickgame node_modules
+	return new Promise((resolve, reject) => {
+		console.log("开始安装OPPO quickgame node_modules,请耐心等待...");
+		let cmd = `npm${commandSuffix}`;
+		let args = ["install"];
+        
+        let cp = childProcess.spawn(cmd, args, {
+            cwd: toolkitPath
+        });
+        
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+		
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+		
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+// 拷贝文件到OPPO快游戏
+gulp.task("copyFileToProj_OPPO", ["installModules_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	// 将临时文件夹中的文件,拷贝到项目中去
+	let originalDir = `${tempReleaseDir}/**/*.*`;
+	let stream = gulp.src(originalDir);
+	return stream.pipe(gulp.dest(path.join(projDir)));
+});
+
+// 拷贝icon到OPPO快游戏
+gulp.task("copyIconToProj_OPPO", ["copyFileToProj_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	let originalDir = config.oppoInfo.icon;
+	let stream = gulp.src(originalDir);
+	return stream.pipe(gulp.dest(path.join(projDir)));
+});
+
+// 清除OPPO快游戏临时目录
+gulp.task("clearTempDir_OPPO", ["copyIconToProj_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	// 删掉临时目录
+	return del([tempReleaseDir], { force: true });
+});
+
+// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem )
+gulp.task("generateSign_OPPO", ["clearTempDir_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+    }
+    if (!config.oppoSign.generateSign) {
+        return;
+    }
+	// https://doc.quickapp.cn/tools/compiling-tools.html
+	return new Promise((resolve, reject) => {
+		let cmd = "openssl";
+		let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem", 
+					"-x509", "-days", "3650", "-out", "certificate.pem"];
+		let opts = {
+			cwd: projDir,
+			shell: true
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			data += "";
+			if (data.includes("Country Name")) {
+				cp.stdin.write(`${config.oppoSign.countryName}\n`);
+				console.log(`Country Name: ${config.oppoSign.countryName}`);
+			} else if (data.includes("Province Name")) {
+				cp.stdin.write(`${config.oppoSign.provinceName}\n`);
+				console.log(`Province Name: ${config.oppoSign.provinceName}`);
+			} else if (data.includes("Locality Name")) {
+				cp.stdin.write(`${config.oppoSign.localityName}\n`);
+				console.log(`Locality Name: ${config.oppoSign.localityName}`);
+			} else if (data.includes("Organization Name")) {
+				cp.stdin.write(`${config.oppoSign.orgName}\n`);
+				console.log(`Organization Name: ${config.oppoSign.orgName}`);
+			} else if (data.includes("Organizational Unit Name")) {
+				cp.stdin.write(`${config.oppoSign.orgUnitName}\n`);
+				console.log(`Organizational Unit Name: ${config.oppoSign.orgUnitName}`);
+			} else if (data.includes("Common Name")) {
+				cp.stdin.write(`${config.oppoSign.commonName}\n`);
+				console.log(`Common Name: ${config.oppoSign.commonName}`);
+			} else if (data.includes("Email Address")) {
+				cp.stdin.write(`${config.oppoSign.emailAddr}\n`);
+				console.log(`Email Address: ${config.oppoSign.emailAddr}`);
+				// cp.stdin.end();
+			}
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+// 拷贝sign文件到指定位置
+gulp.task("copySignFile_OPPO", ["generateSign_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+    }
+    if (config.oppoSign.generateSign) { // 新生成的签名
+        // 移动签名文件到项目中(Laya & OPPO快游戏项目中)
+        let 
+            privatePem = path.join(projDir, "private.pem"),
+            certificatePem = path.join(projDir, "certificate.pem");
+        let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
+        if (!isSignExits) {
+            return;
+        }
+        let 
+            xiaomiDest = `${projDir}/sign/release`,
+            layaDest = `${workSpaceDir}/sign/release`;
+        let stream = gulp.src([privatePem, certificatePem]);
+        return stream.pipe(gulp.dest(xiaomiDest))
+                    .pipe(gulp.dest(layaDest));
+    } else if (config.oppoInfo.useReleaseSign && !config.oppoSign.generateSign) { // 使用release签名,并且没有重新生成
+        // 从项目中将签名拷贝到OPPO快游戏项目中
+        let 
+            privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"),
+            certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem");
+        let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
+        if (!isSignExits) {
+            return;
+        }
+        let 
+            xiaomiDest = `${projDir}/sign/release`;
+        let stream = gulp.src([privatePem, certificatePem]);
+        return stream.pipe(gulp.dest(xiaomiDest));
+    }
+});
+
+gulp.task("deleteSignFile_OPPO", ["copySignFile_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	if (config.oppoSign.generateSign) { // 新生成的签名
+		let 
+            privatePem = path.join(projDir, "private.pem"),
+            certificatePem = path.join(projDir, "certificate.pem");
+		return del([privatePem, certificatePem], { force: true });
+	}
+});
+
+gulp.task("modifyFile_OPPO", ["deleteSignFile_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	// 修改manifest.json文件
+	let manifestPath = path.join(projDir, "manifest.json");
+	let IDEManifestPath = path.join(toolkitPath, "tpl", "manifest.json");
+	if (!fs.existsSync(IDEManifestPath)) {
+		return;
+	}
+	let manifestContent = fs.readFileSync(IDEManifestPath, "utf8");
+	let manifestJson = JSON.parse(manifestContent);
+	manifestJson.package = config.oppoInfo.package;
+	manifestJson.name = config.oppoInfo.name;
+	manifestJson.orientation = config.oppoInfo.orientation;
+	manifestJson.versionName = config.oppoInfo.versionName;
+	manifestJson.versionCode = config.oppoInfo.versionCode;
+	manifestJson.minPlatformVersion = config.oppoInfo.minPlatformVersion;
+	manifestJson.icon = `./${path.basename(config.oppoInfo.icon)}`;
+	if (config.oppoInfo.subpack) {
+		manifestJson.subpackages = config.oppoSubpack;
+	}
+	fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8");
+
+	if (config.version) {
+		let versionPath = projDir + "/version.json";
+		versionCon = fs.readFileSync(versionPath, "utf8");
+		versionCon = JSON.parse(versionCon);
+	}
+	let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] :  "index.js";
+	// OPPO项目,修改main.js
+	let filePath = path.join(projDir, "main.js");
+	// 这个地方,1.x IDE和2.x IDE 不一致
+	let fileContent = `window.navigator.userAgent = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301 OPPO MiniGame NetType/WIFI Language/zh_CN';
+require("./libs/laya.quickgamemini.js");\nrequire("index.js");`;
+	fs.writeFileSync(filePath, fileContent, "utf8");
+
+	// OPPO项目,修改index.js
+	let indexFilePath = path.join(projDir, indexJsStr);
+	if (!fs.existsSync(indexFilePath)) {
+		return;
+	}
+	let indexFileContent = fs.readFileSync(indexFilePath, "utf8");
+	indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./");
+	fs.writeFileSync(indexFilePath, indexFileContent, "utf8");
+});
+
+gulp.task("version_OPPO", ["modifyFile_OPPO"], function () {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	if (config.version) {
+		let versionPath = projDir + "/version.json";
+		let mainJSPath = projDir + "/main.js";
+		let srcList = [versionPath, mainJSPath];
+		return gulp.src(srcList)
+			.pipe(revCollector())
+			.pipe(gulp.dest(projDir));
+	}
+});
+
+// 打包rpk
+gulp.task("buildRPK_OPPO", ["version_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	// 在OPPO轻游戏项目目录中执行:
+    // quickgame pack || quickgame pack release
+    // quickgame subpack --no-build-js || quickgame subpack release --no-build-js
+	let cmdStr = "";
+	let packStr = "pack";
+	let nobuildjs = "";
+	if (config.oppoInfo.subpack) {
+		packStr = "subpack";
+		nobuildjs = "--no-build-js";
+	}
+    if (config.oppoInfo.useReleaseSign) {
+        cmdStr = "release";
+    }
+	return new Promise((resolve, reject) => {
+		let cmd = path.join(toolkitPath, "lib", "bin", `quickgame${commandSuffix}`);
+		let args = [packStr, cmdStr, nobuildjs];
+		let opts = {
+			cwd: projDir
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		// let cp = childProcess.spawn('npx.cmd', ['-v']);
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+gulp.task("pushRPK_OPPO", ["buildRPK_OPPO"], function() {
+	// 如果不是OPPO快游戏
+	if (platform !== "oppogame") {
+		return;
+	}
+	if (!config.oppoInfo.oppoDebug) {
+        return;
+    }
+	// 在OPPO轻游戏项目目录中执行:
+    // adb push dist/game.rpk sdcard/games
+	// adb push idePath/resources/app/out/layarepublic/oppo/instant_app_settings.properties
+	// adb shell am start -n com.nearme.instant.platform/com.oppo.autotest.main.InstantAppActivity
+	return new Promise((resolve, reject) => {
+		let cmd = "adb";
+		let sdGamesPath = config.oppoInfo.subpack ? "sdcard/subPkg" : "sdcard/games";
+		let args = ["push", `dist/${config.oppoInfo.package}${config.oppoInfo.useReleaseSign ? ".signed" : ""}.rpk`, sdGamesPath];
+		let opts = {
+			cwd: projDir
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		// let cp = childProcess.spawn('npx.cmd', ['-v']);
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`1) push_RPK 子进程退出码:${code}`);
+			resolve();
+		});
+	}).then(() => {
+		return new Promise((resolve, reject) => {
+			// 如果是分包,需要修改里面的内容
+			let oppoPropPath = path.join(ideModuleDir, "../", `/out/layarepublic/oppo/instant_app_settings.properties`);
+			if (config.oppoInfo.subpack) {
+				fs.writeFileSync(oppoPropPath, "default_tab_index=4", "utf8");
+			} else {
+				fs.writeFileSync(oppoPropPath, "default_tab_index=2", "utf8");
+			}
+			let cmd = "adb";
+			let args = ["push", oppoPropPath, "sdcard/"];
+			let opts = {
+				cwd: projDir
+			};
+			let cp = childProcess.spawn(cmd, args, opts);
+			// let cp = childProcess.spawn('npx.cmd', ['-v']);
+			cp.stdout.on('data', (data) => {
+				console.log(`stdout: ${data}`);
+			});
+	
+			cp.stderr.on('data', (data) => {
+				console.log(`stderr: ${data}`);
+				// reject();
+			});
+	
+			cp.on('close', (code) => {
+				console.log(`2) push_RPK 子进程退出码:${code}`);
+				resolve();
+			});
+		});
+	}).then(() => {
+		return new Promise((resolve, reject) => {
+			let cmd = "adb";
+			let args = ["shell", "am", "start", "-n", "com.nearme.instant.platform/com.oppo.autotest.main.InstantAppActivity"];
+			let opts = {
+				cwd: projDir
+			};
+			let cp = childProcess.spawn(cmd, args, opts);
+			// let cp = childProcess.spawn('npx.cmd', ['-v']);
+			cp.stdout.on('data', (data) => {
+				console.log(`stdout: ${data}`);
+			});
+	
+			cp.stderr.on('data', (data) => {
+				console.log(`stderr: ${data}`);
+				// reject();
+			});
+	
+			cp.on('close', (code) => {
+				console.log(`3) push_RPK 子进程退出码:${code}`);
+				resolve();
+			});
+		});
+	});
+});
+
+gulp.task("buildOPPOProj", ["pushRPK_OPPO"], function() {
+	console.log("all tasks completed");
+});

+ 726 - 0
.laya/publish_vivogame.js

@@ -0,0 +1,726 @@
+// v1.0.1
+// publish 2.x 也是用这个文件,需要做兼容
+let isPublish2 = process.argv[2].includes("publish_vivogame.js") && process.argv[3].includes("--evn=publish2");
+// 获取Node插件和工作路径
+let ideModuleDir, workSpaceDir;
+if (isPublish2) {
+	//是否使用IDE自带的node环境和插件,设置false后,则使用自己环境(使用命令行方式执行)
+	const useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false;
+	ideModuleDir = useIDENode ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : "";
+	workSpaceDir = useIDENode ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\publish_vivogame.js", "").replace("/.laya/publish_vivogame.js", "") + "/" : "./../";
+} else {
+	ideModuleDir = global.ideModuleDir;
+	workSpaceDir = global.workSpaceDir;
+}
+
+//引用插件模块
+const gulp = require(ideModuleDir + "gulp");
+const fs = require("fs");
+const path = require("path");
+const childProcess = require("child_process");
+const del = require(ideModuleDir + "del");
+const iconv =  require(ideModuleDir + "iconv-lite");
+const revCollector = require(ideModuleDir + 'gulp-rev-collector');
+let commandSuffix = ".cmd";
+let isGlobalQG = true;
+
+let prevTasks = ["packfile"];
+if (isPublish2) {
+	prevTasks = "";
+}
+
+let 
+    config,
+	platform,
+	releaseDir,
+    tempReleaseDir, // vivo临时拷贝目录
+	projDir, // vivo快游戏工程目录
+	isDealNoCompile,
+	physicsLibsPathList = [],
+	isExistEngineFolder = false; // bin目录下是否存在engine文件夹
+let projSrc;
+let versionCon; // 版本管理version.json
+// 创建vivo项目前,拷贝vivo引擎库、修改index.js
+// 应该在publish中的,但是为了方便发布2.0及IDE 1.x,放在这里修改
+gulp.task("preCreate_VIVO", prevTasks, function() {
+	if (isPublish2) {
+		let pubsetPath = path.join(workSpaceDir, ".laya", "pubset.json");
+		let content = fs.readFileSync(pubsetPath, "utf8");
+		let pubsetJson = JSON.parse(content);
+		platform = "vivogame";
+		releaseDir = path.join(workSpaceDir, "release", platform).replace(/\\/g, "/");
+		releaseDir = tempReleaseDir = path.join(releaseDir, "temprelease");
+		config = pubsetJson[6]; // 只用到了 config.vivoInfo|config.vivoSign
+	} else {
+		platform = global.platform;
+		releaseDir = global.releaseDir;
+		tempReleaseDir = global.tempReleaseDir;
+		config = global.config;
+	}
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	if (process.platform === "darwin") {
+		commandSuffix = "";
+	}
+	let copyLibsList = [`${workSpaceDir}/bin/libs/laya.vvmini.js`];
+	var stream = gulp.src(copyLibsList, { base: `${workSpaceDir}/bin` });
+	return stream.pipe(gulp.dest(tempReleaseDir));
+});
+
+gulp.task("copyPlatformFile_VIVO", ["preCreate_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	let vivoAdapterPath = path.join(ideModuleDir, "../", "out", "layarepublic", "LayaAirProjectPack", "lib", "data", "vivofiles");
+	let copyLibsList = [`${vivoAdapterPath}/**/*.*`];
+	var stream = gulp.src(copyLibsList);
+	return stream.pipe(gulp.dest(tempReleaseDir));
+});
+
+// 检查是否全局安装了qgame
+gulp.task("createGlobalQGame_VIVO", ["copyPlatformFile_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	// qgame -V
+	// npm install -g qgame-toolkit
+	return new Promise((resolve, reject) => {
+		let cmd = `qgame${commandSuffix}`;
+		let args = ["-V"];
+		let cp = childProcess.spawn(cmd, args, {
+			shell: true
+		});
+		// let cp = childProcess.spawn('npx.cmd', ['-v']);
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+			if (data.includes("qgame")) {
+				isGlobalQG = false;
+			}
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`);
+			if (data.includes("qgame") && !data.includes("qgame-toolkit")) {
+				isGlobalQG = false;
+			}
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`1 end) qgame -V:${code}`);
+			resolve();
+		});
+	}).then(() => {
+		return new Promise((resolve, reject) => {
+			if (isGlobalQG) {
+				resolve();
+				return;
+			}
+			console.log("全局安装qgame-toolkit");
+			// npm install -g qgame-toolkit
+			let cmd = `npm${commandSuffix}`;
+			let args = ["install", "qgame-toolkit", "-g"];
+			let cp = childProcess.spawn(cmd, args);
+			
+			cp.stdout.on('data', (data) => {
+				console.log(`stdout: ${data}`);
+			});
+	
+			cp.stderr.on('data', (data) => {
+				console.log(`stderr: ${data}`);
+				// reject();
+			});
+	
+			cp.on('close', (code) => {
+				console.log(`2 end) npm install -g qgame-toolkit:${code}`);
+				resolve();
+			});
+		});
+	}).catch((e) => {
+		console.log("catch e", e);
+	});
+});
+
+gulp.task("createProj_VIVO", ["createGlobalQGame_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	releaseDir = path.dirname(releaseDir);
+	projDir = path.join(releaseDir, config.vivoInfo.projName);
+	projSrc = path.join(projDir, "src");
+	// 如果有即存项目,不再新建
+	let isProjExist = fs.existsSync(projDir + "/node_modules") && 
+					  fs.existsSync(projDir + "/sign");
+	if (isProjExist) {
+		return;
+	}
+	// 在项目中创建vivo项目
+	return new Promise((resolve, reject) => {
+		console.log("(proj)开始创建vivo快游戏项目");
+		let cmd = `qgame${commandSuffix}`;
+		let args = ["init", config.vivoInfo.projName];
+        let opts = {
+			cwd: releaseDir,
+			shell: true
+		};
+
+        let cp = childProcess.spawn(cmd, args, opts);
+        
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+			if (data.includes("Init your Project")) {
+				cp.stdin.write(`\n`);
+			}
+			// TODO 这里还是要找原因,不要这样
+			if (data.includes("manifest.json created")) {
+				setTimeout(function() {
+					cp && cp.kill();
+				}, 500);
+			}
+		});
+		
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+		
+		cp.on('close', (code) => {
+			cp = null;
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+gulp.task("installProj_VIVO", ["createProj_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	// 如果有即存项目,不再新建
+	let isProjExist = fs.existsSync(projDir + "/node_modules") && 
+					  fs.existsSync(projDir + "/sign");
+	if (isProjExist) {
+		return;
+	}
+
+	return new Promise((resolve, reject) => {
+		console.log("(proj)下载类库 -> (npm install )");
+		let cmd = `npm${commandSuffix}`;
+		let args = ["install"];
+        let opts = {
+			cwd: projDir
+		};
+
+        let cp = childProcess.spawn(cmd, args, opts);
+        
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+		
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+		
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+// 拷贝文件到vivo快游戏
+gulp.task("copyFileToProj_VIVO", ["installProj_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	// 将临时文件夹中的文件,拷贝到项目中去
+	let originalDir = `${tempReleaseDir}/**/*.*`;
+	let stream = gulp.src(originalDir);
+	return stream.pipe(gulp.dest(path.join(projSrc)));
+});
+
+// 拷贝icon到vivo快游戏
+gulp.task("copyIconToProj_VIVO", ["copyFileToProj_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	let originalDir = config.vivoInfo.icon;
+	let stream = gulp.src(originalDir);
+	return stream.pipe(gulp.dest(projSrc));
+});
+
+// 清除vivo快游戏临时目录
+gulp.task("clearTempDir_VIVO", ["copyIconToProj_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	// 删掉临时目录
+	return del([tempReleaseDir], { force: true });
+});
+
+// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem )
+gulp.task("generateSign_VIVO", ["clearTempDir_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+    }
+    if (!config.vivoSign.generateSign) {
+        return;
+    }
+	// https://doc.quickapp.cn/tools/compiling-tools.html
+	return new Promise((resolve, reject) => {
+		let cmd = "openssl";
+		let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem", 
+					"-x509", "-days", "3650", "-out", "certificate.pem"];
+		let opts = {
+			cwd: projDir,
+			shell: true
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			data += "";
+			if (data.includes("Country Name")) {
+				cp.stdin.write(`${config.vivoSign.countryName}\n`);
+				console.log(`Country Name: ${config.vivoSign.countryName}`);
+			} else if (data.includes("Province Name")) {
+				cp.stdin.write(`${config.vivoSign.provinceName}\n`);
+				console.log(`Province Name: ${config.vivoSign.provinceName}`);
+			} else if (data.includes("Locality Name")) {
+				cp.stdin.write(`${config.vivoSign.localityName}\n`);
+				console.log(`Locality Name: ${config.vivoSign.localityName}`);
+			} else if (data.includes("Organization Name")) {
+				cp.stdin.write(`${config.vivoSign.orgName}\n`);
+				console.log(`Organization Name: ${config.vivoSign.orgName}`);
+			} else if (data.includes("Organizational Unit Name")) {
+				cp.stdin.write(`${config.vivoSign.orgUnitName}\n`);
+				console.log(`Organizational Unit Name: ${config.vivoSign.orgUnitName}`);
+			} else if (data.includes("Common Name")) {
+				cp.stdin.write(`${config.vivoSign.commonName}\n`);
+				console.log(`Common Name: ${config.vivoSign.commonName}`);
+			} else if (data.includes("Email Address")) {
+				cp.stdin.write(`${config.vivoSign.emailAddr}\n`);
+				console.log(`Email Address: ${config.vivoSign.emailAddr}`);
+				// cp.stdin.end();
+			}
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+// 拷贝sign文件到指定位置
+gulp.task("copySignFile_VIVO", ["generateSign_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+    }
+    if (config.vivoSign.generateSign) { // 新生成的签名
+        // 移动签名文件到项目中(Laya & vivo快游戏项目中)
+        let 
+            privatePem = path.join(projDir, "private.pem"),
+            certificatePem = path.join(projDir, "certificate.pem");
+        let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
+        if (!isSignExits) {
+            return;
+        }
+        let 
+            xiaomiDest = `${projDir}/sign/release`,
+            layaDest = `${workSpaceDir}/sign/release`;
+        let stream = gulp.src([privatePem, certificatePem]);
+        return stream.pipe(gulp.dest(xiaomiDest))
+                    .pipe(gulp.dest(layaDest));
+    } else if (config.vivoInfo.useReleaseSign && !config.vivoSign.generateSign) { // 使用release签名,并且没有重新生成
+        // 从项目中将签名拷贝到vivo快游戏项目中
+        let 
+            privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"),
+            certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem");
+        let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
+        if (!isSignExits) {
+            return;
+        }
+        let 
+            xiaomiDest = `${projDir}/sign/release`;
+        let stream = gulp.src([privatePem, certificatePem]);
+        return stream.pipe(gulp.dest(xiaomiDest));
+    }
+});
+
+gulp.task("deleteSignFile_VIVO", ["copySignFile_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	if (config.vivoSign.generateSign) { // 新生成的签名
+		let 
+            privatePem = path.join(projDir, "private.pem"),
+            certificatePem = path.join(projDir, "certificate.pem");
+		return del([privatePem, certificatePem], { force: true });
+	}
+});
+
+gulp.task("modifyFile_VIVO", ["deleteSignFile_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	// 修改manifest.json文件
+	let manifestPath = path.join(projSrc, "manifest.json");
+	if (!fs.existsSync(manifestPath)) {
+		return;
+	}
+	let manifestContent = fs.readFileSync(manifestPath, "utf8");
+	let manifestJson = JSON.parse(manifestContent);
+	manifestJson.package = config.vivoInfo.package;
+	manifestJson.name = config.vivoInfo.name;
+	manifestJson.orientation = config.vivoInfo.orientation;
+	manifestJson.deviceOrientation = config.vivoInfo.orientation;
+	manifestJson.versionName = config.vivoInfo.versionName;
+	manifestJson.versionCode = config.vivoInfo.versionCode;
+	manifestJson.minPlatformVersion = config.vivoInfo.minPlatformVersion;
+	manifestJson.icon = `/${path.basename(config.vivoInfo.icon)}`;
+	fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8");
+
+	if (config.version) {
+		let versionPath = projSrc + "/version.json";
+		versionCon = fs.readFileSync(versionPath, "utf8");
+		versionCon = JSON.parse(versionCon);
+	}
+	let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] :  "index.js";
+	// 修改game.js文件
+	let content = `require("./qgame-adapter.js");\nif(!window.navigator)\n\twindow.navigator = {};\nwindow.navigator.userAgent = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301 VVGame NetType/WIFI Language/zh_CN';\nrequire("./libs/laya.vvmini.js");\nrequire("./index.js");`;
+	let gameJsPath = path.join(projSrc, "game.js");
+	fs.writeFileSync(gameJsPath, content, "utf8");
+
+	// vivo项目,修改index.js
+	let filePath = path.join(projSrc, indexJsStr);
+	if (!fs.existsSync(filePath)) {
+		return;
+	}
+	let fileContent = fs.readFileSync(filePath, "utf8");
+	fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./");
+	fs.writeFileSync(filePath, fileContent, "utf8");
+})
+
+gulp.task("version_VIVO", ["modifyFile_VIVO"], function () {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	if (config.version) {
+		let versionPath = projSrc + "/version.json";
+		let mainJSPath = projSrc + "/game.js";
+		let srcList = [versionPath, mainJSPath];
+		return gulp.src(srcList)
+			.pipe(revCollector())
+			.pipe(gulp.dest(projSrc));
+	}
+});
+
+// 处理engine文件夹
+gulp.task("dealEngineFolder1_VIVO", ["version_VIVO"], function() {
+	// 如果项目中游engine文件夹,我们默认该开发者是熟悉VIVO发布流程的,已经处理好所有的逻辑
+	// 值得注意的:
+	// 1) 如果有engine文件夹而未处理2D物理库(box2d.js/physics.js),项目将无法运行
+	// 2) 如果未处理3D物理库(physics3D.js),打包时间将会很长
+
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	let engineFolder = path.join(projDir, "src", "engine");
+	isExistEngineFolder = fs.existsSync(engineFolder);
+	if (!isExistEngineFolder) {
+		return;
+	}
+
+	let adapterOriginalPath = path.join(projDir, "src", "qgame-adapter.js");
+
+	let vivoConfigPath = path.join(ideModuleDir, "../", "out", "layarepublic", "LayaAirProjectPack", "lib", "data", "addi", "vivo");
+
+	// 不想写一堆task任务,500ms默认拷贝完成吧
+	// 未来有了更好的解决方案再修改
+	return new Promise(function(resolve, reject) {
+		// 拷贝webpack.config.js
+		setTimeout(resolve, 500);
+		var stream = gulp.src([`${vivoConfigPath}/**/*.*`]);
+		return stream.pipe(gulp.dest(projDir));
+	}).then(function() {
+		return new Promise(function(resolve, reject) {
+			// 将engine文件夹拷贝到projRoot下
+			setTimeout(resolve, 500);
+			var stream = gulp.src([`${engineFolder}/**/*.*`], {base: `${projDir}/src`});
+			return stream.pipe(gulp.dest(projDir));
+		});
+	}).then(function() {
+		return new Promise(function(resolve, reject) {
+			// 将adapter.js拷贝到engine文件夹中
+			setTimeout(resolve, 500);
+			var stream = gulp.src([adapterOriginalPath]);
+			return stream.pipe(gulp.dest(`${projDir}/engine`));
+		});
+	}).then(function() {
+		return new Promise(function(resolve, reject) {
+			// 删掉src下的engine和adapter
+			setTimeout(resolve, 500);
+			return del([engineFolder, adapterOriginalPath], { force: true });
+		});
+	}).catch(function(err) {
+		console.log(err);
+	});
+});
+
+gulp.task("dealEngineFolder2_VIVO", ["dealEngineFolder1_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	if (!isExistEngineFolder) {
+		return;
+	}
+	
+	let engineFolder = path.join(projDir, "engine");
+	let engineFileList = fs.readdirSync(engineFolder);
+	// 修改webpack.config.js
+	let vvConfigPath = path.join(projDir, "config", "webpack.config.js");
+	let content = fs.readFileSync(vvConfigPath, "utf8");
+	let externalsStr = '{\n';
+	let libName;
+	for (let i = 0, len = engineFileList.length; i < len; i++) {
+		libName = engineFileList[i];
+		if (i !== 0) {
+			externalsStr += ',\n';
+		}
+		externalsStr += `'./${libName}':'commonjs ./${libName}'`;
+	}
+	externalsStr += '\n}';
+	content = content.replace("EXTERNALS_PLACE_HOLDER", externalsStr);
+	fs.writeFileSync(vvConfigPath, content, "utf8");
+});
+
+// 如果项目中用到了 box2d.js|laya.physics.js/laya.physics3D.js ,需要特殊处理
+gulp.task("dealNoCompile1_VIVO", ["dealEngineFolder2_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	if (isExistEngineFolder) {
+		return;
+	}
+	// 如果没有使用物理,则忽略这一步
+	let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] :  "index.js";
+	let filePath = path.join(projSrc, indexJsStr);
+	if (!fs.existsSync(filePath)) {
+		return;
+	}
+	isDealNoCompile = true;
+
+	// 拷贝webpack.config.js
+	let vivoConfigPath = path.join(ideModuleDir, "../", "out", "layarepublic", "LayaAirProjectPack", "lib", "data", "addi", "vivo");
+	let copyConfigList = [`${vivoConfigPath}/**/*.*`];
+	var stream = gulp.src(copyConfigList);
+	return stream.pipe(gulp.dest(projDir));
+});
+
+gulp.task("dealNoCompile2_VIVO", ["dealNoCompile1_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	if (!isDealNoCompile) {
+		return;
+	}
+
+	// let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] :  "index.js";
+	// let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] :  "js/bundle.js";
+	// let box2dJsStr = (versionCon && versionCon["libs/box2d.js"]) ? versionCon["libs/box2d.js"] :  "libs/box2d.js";
+	// let physicsJsStr = (versionCon && versionCon["libs/laya.physics.js"]) ? versionCon["libs/laya.physics.js"] :  "libs/laya.physics.js";
+	// let physics3DJsStr = (versionCon && versionCon["libs/laya.physics3D.js"]) ? versionCon["libs/laya.physics3D.js"] :  "libs/laya.physics3D.js";
+
+	// // 修改index.js,去掉物理库前面的libs
+	// let filePath = path.join(projSrc, indexJsStr);
+	// let fileContent = fs.readFileSync(filePath, "utf8");
+	// let physicsNameList = [];
+
+	// if (fileContent.includes(bundleJsStr)) {
+	// 	let adapterJsPath = path.join(projSrc, bundleJsStr);
+	// 	physicsNameList.push(bundleJsStr);
+	// 	physicsLibsPathList.push(adapterJsPath);
+	// }
+	// if (fileContent.includes(box2dJsStr)) {
+	// 	let libPath = path.join(projSrc, box2dJsStr);
+	// 	physicsNameList.push(box2dJsStr);
+	// 	physicsLibsPathList.push(libPath);
+	// }
+	// if (fileContent.includes(physicsJsStr)) {
+	// 	let libPath = path.join(projSrc, physicsJsStr);
+	// 	physicsNameList.push(physicsJsStr);
+	// 	physicsLibsPathList.push(libPath);
+	// }
+	// if (fileContent.includes(physics3DJsStr)) {
+	// 	let libPath = path.join(projSrc, physics3DJsStr);
+	// 	physicsNameList.push(physics3DJsStr);
+	// 	physicsLibsPathList.push(libPath);
+	// }
+	// if (physicsLibsPathList.length > 0) {
+	// 	let adapterJsPath = path.join(projSrc, "qgame-adapter.js");
+	// 	physicsNameList.push("qgame-adapter.js");
+	// 	physicsLibsPathList.push(adapterJsPath);
+	// }
+
+
+	// 将js/bundle.js | libs/*.* qgame-adapter.js 全放到engine文件夹中
+	let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] :  "index.js";
+	let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] :  "js/bundle.js";
+
+	// 修改index.js,去掉物理库前面的libs
+	let filePath = path.join(projSrc, indexJsStr);
+	let fileContent = fs.readFileSync(filePath, "utf8");
+	let physicsNameList = [];
+
+	if (fileContent.includes(bundleJsStr)) {
+		let adapterJsPath = path.join(projSrc, bundleJsStr);
+		physicsNameList.push(bundleJsStr);
+		physicsLibsPathList.push(adapterJsPath);
+	}
+	let libsList = fs.readdirSync(path.join(projSrc, "libs"));
+	let libsFileName, libsFilePath;
+	for (let i = 0, len = libsList.length; i < len; i++) {
+		libsFileName = libsList[i];
+		libsFilePath = path.join(projSrc, "libs", libsFileName);
+		physicsNameList.push(`libs/${libsFileName}`);
+		physicsLibsPathList.push(libsFilePath);
+	}
+	if (physicsLibsPathList.length > 0) {
+		let adapterJsPath = path.join(projSrc, "qgame-adapter.js");
+		physicsNameList.push("qgame-adapter.js");
+		physicsLibsPathList.push(adapterJsPath);
+	}
+
+	// 修改webpack.config.js
+	let vvConfigPath = path.join(projDir, "config", "webpack.config.js");
+	let content = fs.readFileSync(vvConfigPath, "utf8");
+	let externalsStr = '{\n';
+	let libName;
+	for (let i = 0, len = physicsNameList.length; i < len; i++) {
+		libName = physicsNameList[i];
+		if (i !== 0) {
+			externalsStr += ',\n';
+		}
+		externalsStr += `'./${libName}':'commonjs ./${libName}'`;
+	}
+	externalsStr += '\n}';
+	content = content.replace("EXTERNALS_PLACE_HOLDER", externalsStr);
+	fs.writeFileSync(vvConfigPath, content, "utf8");
+
+	// 将物理库、qgame-adapter.js拷贝到engine中
+	var stream = gulp.src(physicsLibsPathList, {base: projSrc});
+	return stream.pipe(gulp.dest(path.join(projDir, "engine")));
+});
+
+gulp.task("dealNoCompile3_VIVO", ["dealNoCompile2_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	if (!isDealNoCompile || physicsLibsPathList.length === 0) {
+		return;
+	}
+	return del(physicsLibsPathList, { force: true });
+});
+
+// 打包rpk
+gulp.task("buildRPK_VIVO", ["dealNoCompile3_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	// 在vivo轻游戏项目目录中执行:
+    // npm run build || npm run release
+    let cmdStr = "build";
+    if (config.vivoInfo.useReleaseSign) {
+        cmdStr = "release";
+    }
+	return new Promise((resolve, reject) => {
+		let cmd = `npm${commandSuffix}`;
+		let args = ["run", cmdStr];
+		let opts = {
+			cwd: projDir
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		// let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']);
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`);
+			
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+gulp.task("showQRCode_VIVO", ["buildRPK_VIVO"], function() {
+	// 如果不是vivo快游戏
+	if (platform !== "vivogame") {
+		return;
+	}
+	// 在vivo轻游戏项目目录中执行:
+	// npm run server
+	return new Promise((resolve, reject) => {
+		let cmd = `npm${commandSuffix}`;
+		let args = ["run", "server"];
+		let opts = {
+			cwd: projDir
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		// let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']);
+		cp.stdout.on('data', (data) => {
+			console.log(`${data}`);
+			// 输出pid,macos要用: macos无法kill进程树,也无法执行命令获取3000端口pid(没有查询权限),导致无法kill这个进程
+			console.log('vv_qrcode_pid:' + cp.pid);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`);
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+
+gulp.task("buildVivoProj", ["showQRCode_VIVO"], function() {
+	console.log("all tasks completed");
+});

+ 518 - 0
.laya/publish_xmgame.js

@@ -0,0 +1,518 @@
+// v1.1.1
+// publish 2.x 也是用这个文件,需要做兼容
+let isPublish2 = process.argv[2].includes("publish_xmgame.js") && process.argv[3].includes("--evn=publish2");
+// 获取Node插件和工作路径
+let ideModuleDir, workSpaceDir;
+if (isPublish2) {
+	//是否使用IDE自带的node环境和插件,设置false后,则使用自己环境(使用命令行方式执行)
+	const useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false;
+	ideModuleDir = useIDENode ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : "";
+	workSpaceDir = useIDENode ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\publish_xmgame.js", "").replace("/.laya/publish_xmgame.js", "") + "/" : "./../";
+} else {
+	ideModuleDir = global.ideModuleDir;
+	workSpaceDir = global.workSpaceDir;
+}
+
+//引用插件模块
+const gulp = require(ideModuleDir + "gulp");
+const fs = require("fs");
+const path = require("path");
+const childProcess = require("child_process");
+const del = require(ideModuleDir + "del");
+const revCollector = require(ideModuleDir + 'gulp-rev-collector');
+let commandSuffix = ".cmd";
+
+let prevTasks = ["packfile"];
+if (isPublish2) {
+	prevTasks = "";
+}
+
+let 
+    config,
+	platform,
+	releaseDir,
+    tempReleaseDir, // 小米临时拷贝目录
+	projDir; // 小米快游戏工程目录
+let IDEXMProjPath,
+	isUpdateIDEXMProj = false;
+let versionCon; // 版本管理version.json
+// 创建小米项目前,拷贝小米引擎库、修改index.js
+// 应该在publish中的,但是为了方便发布2.0及IDE 1.x,放在这里修改
+gulp.task("preCreate_XM", prevTasks, function() {
+	if (isPublish2) {
+		let pubsetPath = path.join(workSpaceDir, ".laya", "pubset.json");
+		let content = fs.readFileSync(pubsetPath, "utf8");
+		let pubsetJson = JSON.parse(content);
+		platform = "xmgame";
+		releaseDir = path.join(workSpaceDir, "release", platform).replace(/\\/g, "/");
+		releaseDir = tempReleaseDir = path.join(releaseDir, "temprelease");
+		config = pubsetJson[4]; // 只用到了 config.xmInfo|config.xmSign
+	} else {
+		platform = global.platform;
+		releaseDir = global.releaseDir;
+		tempReleaseDir = global.tempReleaseDir;
+		config = global.config;
+	}
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	if (process.platform === "darwin") {
+		commandSuffix = "";
+	}
+	let copyLibsList = [`${workSpaceDir}/bin/libs/laya.xmmini.js`];
+	var stream = gulp.src(copyLibsList, { base: `${workSpaceDir}/bin` });
+	return stream.pipe(gulp.dest(tempReleaseDir));
+});
+
+gulp.task("copyPlatformFile_XM", ["preCreate_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	let xmAdapterPath = path.join(ideModuleDir, "../", "out", "layarepublic", "LayaAirProjectPack", "lib", "data", "xmfiles");
+	let copyLibsList = [`${xmAdapterPath}/**/*.*`];
+	var stream = gulp.src(copyLibsList);
+	return stream.pipe(gulp.dest(tempReleaseDir));
+});
+
+// 新建小米项目-小米项目与其他项目不同,需要新建小米快游戏项目,并打包成.rpk文件
+gulp.task("checkIDEProj_XM", ["copyPlatformFile_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	if (!ideModuleDir) {
+		return;
+	}
+	IDEXMProjPath = path.join(ideModuleDir, "../", "out", "layarepublic", "xm");
+	if (process.platform === "darwin") {
+		return;
+	}
+	let ideLastXMProjPath = path.join(IDEXMProjPath, config.xmInfo.projName);
+	// 如果IDE中没有小米项目,跳过这一步
+	let isProjExist = fs.existsSync(ideLastXMProjPath + "/node_modules") && 
+					  fs.existsSync(ideLastXMProjPath + "/sign");
+	if (!isProjExist) {
+		console.log("IDE中没有小米项目,跳过检查小米项目版本号这一步");
+		return;
+	}
+	// 如果IDE中项目已经存在了,检查版本号
+	// npm view quickgame-cli version
+	// npm ls quickgame-cli
+	let remoteVersion, localVersion;
+	let isGetRemote, isGetLocal;
+	return new Promise((resolve, reject) => { // 远程版本号
+		childProcess.exec("npm view quickgame-cli version", function(error, stdout, stderr) {
+			if (!stdout) { // 获取 quickgame-cli 远程版本号失败
+				reject();
+				return;
+			}
+			remoteVersion = stdout;
+			isGetRemote = true;
+			if (isGetRemote && isGetLocal) {
+				resolve();
+			}
+		});
+		childProcess.exec("npm ls quickgame-cli", { cwd: ideLastXMProjPath }, function(error, stdout, stderr) {
+			if (!stdout) { // 获取 quickgame-cli 本地版本号失败
+				reject();
+				return;
+			}
+			localVersion = stdout.match(/quickgame-cli@(.+)/);
+			localVersion = localVersion && localVersion[1];
+			isGetLocal = true;
+			if (isGetRemote && isGetLocal) {
+				resolve();
+			}
+		});
+		setTimeout(() => {
+			if (!isGetLocal || !isGetRemote) {
+				console.log("获取远程版本号或本地版本号失败");
+				reject();
+				return;
+			}
+		}, 10000);
+	}).then(() => { // 比较两个版本号
+		if (!remoteVersion || !localVersion) {
+			console.log("获取远程版本号或本地版本号失败!");
+		}
+		console.log("quickgame-cli -> ", localVersion, "|", remoteVersion);
+		if (remoteVersion.trim() !== localVersion.trim()) { // 仅当两个版本号都获取到并且不相等,置为需要更新(true)
+			isUpdateIDEXMProj = true;
+		}
+	}).catch((e) => {
+		console.log("获取远程版本号或本地版本号失败 -> ", remoteVersion, "|", localVersion);
+		console.log(e);
+	});
+});
+
+gulp.task("createIDEProj_XM", ["checkIDEProj_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	if (!ideModuleDir) {
+		return;
+	}
+	if (process.platform === "darwin") {
+		return;
+	}
+	let ideLastXMProjPath = path.join(IDEXMProjPath, config.xmInfo.projName);
+	// 如果有即存项目,不再新建
+	let isProjExist = fs.existsSync(ideLastXMProjPath + "/node_modules") && 
+					  fs.existsSync(ideLastXMProjPath + "/sign");
+	if (isProjExist && !isUpdateIDEXMProj) { // 项目存在并且不需要更新IDE中的小米项目
+		return;
+	}
+	return new Promise((resolve, reject) => {
+		console.log("(IDE)开始创建小米快游戏项目,请耐心等待(预计需要10分钟)...");
+		let cmd = `npx${commandSuffix}`;
+		let args = ["create-quickgame", config.xmInfo.projName, `path=${IDEXMProjPath}`,
+					`package=${config.xmInfo.package}`, `versionName=${config.xmInfo.versionName}`,
+					`versionCode=${config.xmInfo.versionCode}`, `minPlatformVersion=${config.xmInfo.minPlatformVersion}`,
+                    `icon=/layaicon/${path.basename(config.xmInfo.icon)}`, `name=${config.xmInfo.name}`, `rebuild=true`];
+        console.log(JSON.stringify(args));
+        
+        let cp = childProcess.spawn(cmd, args);
+        
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+		
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+		
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+gulp.task("createProj_XM", ["createIDEProj_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	releaseDir = path.dirname(releaseDir);
+	projDir = path.join(releaseDir, config.xmInfo.projName);
+	// 如果有即存项目,不再新建
+	let isProjExist = fs.existsSync(projDir + "/node_modules") && 
+					  fs.existsSync(projDir + "/sign");
+	if (isProjExist) {
+		return;
+	}
+	// 如果IDE中有即存项目,不再新建,从IDE中拷贝
+	let ideLastXMProjPath = path.join(IDEXMProjPath, config.xmInfo.projName);
+	let isIDEXMProjExist = fs.existsSync(ideLastXMProjPath + "/node_modules") && 
+						fs.existsSync(ideLastXMProjPath + "/sign");
+	if (isIDEXMProjExist) { // 如果用的IDE并且有IDEXM目录
+		console.log("使用IDE中的小米游戏项目,拷贝...");
+		// node-glob语法中,* 无法匹配 .开头的文件(夹),必须手动匹配
+		let IDEXMProjPathStr = [`${IDEXMProjPath}/**/*.*`, `${ideLastXMProjPath}/node_modules/.bin/*.*`];
+		var stream = gulp.src(IDEXMProjPathStr, { base: IDEXMProjPath});
+		return stream.pipe(gulp.dest(releaseDir));
+	}
+	// 在项目中创建小米项目
+	return new Promise((resolve, reject) => {
+		console.log("(proj)开始创建小米快游戏项目,请耐心等待(预计需要10分钟)...");
+		let cmd = `npx${commandSuffix}`;
+		let args = ["create-quickgame", config.xmInfo.projName, `path=${releaseDir}`,
+					`package=${config.xmInfo.package}`, `versionName=${config.xmInfo.versionName}`,
+					`versionCode=${config.xmInfo.versionCode}`, `minPlatformVersion=${config.xmInfo.minPlatformVersion}`,
+                    `icon=/layaicon/${path.basename(config.xmInfo.icon)}`, `name=${config.xmInfo.name}`, `rebuild=true`];
+        console.log(JSON.stringify(args));
+        
+        let cp = childProcess.spawn(cmd, args);
+        
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+		
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+		
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+// 拷贝文件到小米快游戏
+gulp.task("copyFileToProj_XM", ["createProj_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	// 将临时文件夹中的文件,拷贝到项目中去
+	let originalDir = `${tempReleaseDir}/**/*.*`;
+	let stream = gulp.src(originalDir);
+	return stream.pipe(gulp.dest(path.join(projDir)));
+});
+
+// 拷贝icon到小米快游戏
+gulp.task("copyIconToProj_XM", ["copyFileToProj_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	let originalDir = config.xmInfo.icon;
+	let stream = gulp.src(originalDir);
+	return stream.pipe(gulp.dest(path.join(projDir, "layaicon")));
+});
+
+// 清除小米快游戏临时目录
+gulp.task("clearTempDir_XM", ["copyIconToProj_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	// 删掉临时目录
+	return del([tempReleaseDir], { force: true });
+});
+
+// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem )
+gulp.task("generateSign_XM", ["clearTempDir_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+    }
+    if (!config.xmSign.generateSign) {
+        return;
+    }
+	// https://doc.quickapp.cn/tools/compiling-tools.html
+	return new Promise((resolve, reject) => {
+		let cmd = "openssl";
+		let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem", 
+					"-x509", "-days", "3650", "-out", "certificate.pem"];
+		let opts = {
+			cwd: projDir,
+			shell: true
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			data += "";
+			if (data.includes("Country Name")) {
+				cp.stdin.write(`${config.xmSign.countryName}\n`);
+				console.log(`Country Name: ${config.xmSign.countryName}`);
+			} else if (data.includes("Province Name")) {
+				cp.stdin.write(`${config.xmSign.provinceName}\n`);
+				console.log(`Province Name: ${config.xmSign.provinceName}`);
+			} else if (data.includes("Locality Name")) {
+				cp.stdin.write(`${config.xmSign.localityName}\n`);
+				console.log(`Locality Name: ${config.xmSign.localityName}`);
+			} else if (data.includes("Organization Name")) {
+				cp.stdin.write(`${config.xmSign.orgName}\n`);
+				console.log(`Organization Name: ${config.xmSign.orgName}`);
+			} else if (data.includes("Organizational Unit Name")) {
+				cp.stdin.write(`${config.xmSign.orgUnitName}\n`);
+				console.log(`Organizational Unit Name: ${config.xmSign.orgUnitName}`);
+			} else if (data.includes("Common Name")) {
+				cp.stdin.write(`${config.xmSign.commonName}\n`);
+				console.log(`Common Name: ${config.xmSign.commonName}`);
+			} else if (data.includes("Email Address")) {
+				cp.stdin.write(`${config.xmSign.emailAddr}\n`);
+				console.log(`Email Address: ${config.xmSign.emailAddr}`);
+				// cp.stdin.end();
+			}
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+// 拷贝sign文件到指定位置
+gulp.task("copySignFile_XM", ["generateSign_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+    }
+    if (config.xmSign.generateSign) { // 新生成的签名
+        // 移动签名文件到项目中(Laya & 小米快游戏项目中)
+        let 
+            privatePem = path.join(projDir, "private.pem"),
+            certificatePem = path.join(projDir, "certificate.pem");
+        let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
+        if (!isSignExits) {
+            return;
+        }
+        let 
+            xiaomiDest = `${projDir}/sign/release`,
+            layaDest = `${workSpaceDir}/sign/release`;
+        let stream = gulp.src([privatePem, certificatePem]);
+        return stream.pipe(gulp.dest(xiaomiDest))
+                    .pipe(gulp.dest(layaDest));
+    } else if (config.xmInfo.useReleaseSign && !config.xmSign.generateSign) { // 使用release签名,并且没有重新生成
+        // 从项目中将签名拷贝到小米快游戏项目中
+        let 
+            privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"),
+            certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem");
+        let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
+        if (!isSignExits) {
+            return;
+        }
+        let 
+            xiaomiDest = `${projDir}/sign/release`;
+        let stream = gulp.src([privatePem, certificatePem]);
+        return stream.pipe(gulp.dest(xiaomiDest));
+    }
+});
+
+gulp.task("deleteSignFile_XM", ["copySignFile_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	if (config.xmSign.generateSign) { // 新生成的签名
+		let 
+            privatePem = path.join(projDir, "private.pem"),
+            certificatePem = path.join(projDir, "certificate.pem");
+		return del([privatePem, certificatePem], { force: true });
+	}
+});
+
+gulp.task("modifyFile_XM", ["deleteSignFile_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	// 修改manifest.json文件
+	let manifestPath = path.join(projDir, "manifest.json");
+	if (!fs.existsSync(manifestPath)) {
+		return;
+	}
+	let manifestContent = fs.readFileSync(manifestPath, "utf8");
+	let manifestJson = JSON.parse(manifestContent);
+	manifestJson.package = config.xmInfo.package;
+	manifestJson.name = config.xmInfo.name;
+	manifestJson.orientation = config.xmInfo.orientation;
+	manifestJson.versionName = config.xmInfo.versionName;
+	manifestJson.versionCode = config.xmInfo.versionCode;
+	manifestJson.minPlatformVersion = config.xmInfo.minPlatformVersion;
+	manifestJson.icon = `/layaicon/${path.basename(config.xmInfo.icon)}`;
+	fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8");
+
+	if (config.version) {
+		let versionPath = projDir + "/version.json";
+		versionCon = fs.readFileSync(versionPath, "utf8");
+		versionCon = JSON.parse(versionCon);
+	}
+	let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] :  "index.js";
+	// 修改main.js文件
+	let content = 'require("./qg-adapter.js");\nrequire("./libs/laya.xmmini.js");\nrequire("./index.js");';
+	let mainJsPath = path.join(projDir, "main.js");
+	fs.writeFileSync(mainJsPath, content, "utf8");
+
+	// 小米项目,修改index.js
+	let filePath = path.join(projDir, indexJsStr);
+	if (!fs.existsSync(filePath)) {
+		return;
+	}
+	let fileContent = fs.readFileSync(filePath, "utf8");
+	fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./");
+	fs.writeFileSync(filePath, fileContent, "utf8");
+})
+
+gulp.task("version_XM", ["modifyFile_XM"], function () {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	if (config.version) {
+		let versionPath = projDir + "/version.json";
+		let mainJSPath = projDir + "/main.js";
+		let srcList = [versionPath, mainJSPath];
+		return gulp.src(srcList)
+			.pipe(revCollector())
+			.pipe(gulp.dest(projDir));
+	}
+});
+
+// 打包rpk
+gulp.task("buildRPK_XM", ["version_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	// 在小米轻游戏项目目录中执行:
+    // npm run build || npm run release
+    let cmdStr = "build";
+    if (config.xmInfo.useReleaseSign) {
+        cmdStr = "release";
+    }
+	return new Promise((resolve, reject) => {
+		let cmd = `npm${commandSuffix}`;
+		let args = ["run", cmdStr];
+		let opts = {
+			cwd: projDir
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		// let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']);
+		cp.stdout.on('data', (data) => {
+			console.log(`stdout: ${data}`);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+gulp.task("showQRCode_XM", ["buildRPK_XM"], function() {
+	// 如果不是小米快游戏
+	if (platform !== "xmgame") {
+		return;
+	}
+	// 在小米轻游戏项目目录中执行:
+	// npm run server
+	return new Promise((resolve, reject) => {
+		let cmd = `npm${commandSuffix}`;
+		let args = ["run", "server"];
+		let opts = {
+			cwd: projDir
+		};
+		let cp = childProcess.spawn(cmd, args, opts);
+		// let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']);
+		cp.stdout.on('data', (data) => {
+			console.log(`${data}`);
+			// 输出pid,macos要用: macos无法kill进程树,也无法执行命令获取3000端口pid(没有查询权限),导致无法kill这个进程
+			console.log('xm_qrcode_pid:' + cp.pid);
+		});
+
+		cp.stderr.on('data', (data) => {
+			console.log(`stderr: ${data}`);
+			// reject();
+		});
+
+		cp.on('close', (code) => {
+			console.log(`子进程退出码:${code}`);
+			resolve();
+		});
+	});
+});
+
+
+gulp.task("buildXiaomiProj", ["showQRCode_XM"], function() {
+	console.log("all tasks completed");
+});

+ 1 - 0
DateTheGirl.laya

@@ -0,0 +1 @@
+{"proName":"DateTheGirl","engineType":0,"proType":1,"layaProType":0,"version":"2.1.0"}

BIN
bin/Resources/-10.png


BIN
bin/Resources/-11.png


BIN
bin/Resources/-7.png


BIN
bin/Resources/-9.png


BIN
bin/Resources/1.png


BIN
bin/Resources/2.png


BIN
bin/Resources/3.png


BIN
bin/Resources/4.png


BIN
bin/Resources/5.png


BIN
bin/Resources/6.png


BIN
bin/Resources/BG.png


ファイルの差分が大きいため隠しています
+ 1 - 0
bin/fileconfig.json


+ 32 - 0
bin/index.html

@@ -0,0 +1,32 @@
+<html>
+
+<head>
+    <title>www.layabox.com</title>
+    <meta charset='utf-8' />
+    <meta name='renderer' content='webkit' />
+    <meta name='viewport' content='width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no'
+    />
+    <meta name='apple-mobile-web-app-capable' content='yes' />
+    <meta name='full-screen' content='true' />
+    <meta name='x5-fullscreen' content='true' />
+    <meta name='360-fullscreen' content='true' />
+    <meta name='laya' screenorientation='landscape' />
+    <meta http-equiv='expires' content='0' />
+    <meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1' />
+    <meta http-equiv='expires' content='0' />
+    <meta http-equiv='Cache-Control' content='no-siteapp' />
+</head>
+
+<body>
+    <script type="text/javascript">
+        function loadLib(url) {
+            var script = document.createElement("script");
+            script.async = false;
+            script.src = url;
+            document.body.appendChild(script);
+        }
+    </script>
+    <script type="text/javascript" src="index.js"></script>
+</body>
+
+</html>

+ 15 - 0
bin/index.js

@@ -0,0 +1,15 @@
+/**
+ * 设置LayaNative屏幕方向,可设置以下值
+ * landscape           横屏
+ * portrait            竖屏
+ * sensor_landscape    横屏(双方向)
+ * sensor_portrait     竖屏(双方向)
+ */
+window.screenOrientation = "sensor_landscape";
+
+//-----libs-begin-----
+loadLib("libs/laya.core.js")
+loadLib("libs/laya.ui.js")
+loadLib("libs/laya.physics.js")
+//-----libs-end-------
+loadLib("js/bundle.js");

ファイルの差分が大きいため隠しています
+ 3746 - 0
bin/libs/bytebuffer.js


ファイルの差分が大きいため隠しています
+ 2357 - 0
bin/libs/domparserinone.js


ファイルの差分が大きいため隠しています
+ 4212 - 0
bin/libs/laya.ani.js


ファイルの差分が大きいため隠しています
+ 1682 - 0
bin/libs/laya.bdmini.js


ファイルの差分が大きいため隠しています
+ 25646 - 0
bin/libs/laya.core.js


ファイルの差分が大きいため隠しています
+ 31335 - 0
bin/libs/laya.d3.js


ファイルの差分が大きいため隠しています
+ 9815 - 0
bin/libs/laya.debugtool.js


+ 653 - 0
bin/libs/laya.device.js

@@ -0,0 +1,653 @@
+(function (exports, Laya) {
+	'use strict';
+
+	class AccelerationInfo {
+	    constructor() {
+	    }
+	}
+
+	class RotationInfo {
+	    constructor() {
+	    }
+	}
+
+	class Accelerator extends Laya.EventDispatcher {
+	    constructor(singleton) {
+	        super();
+	        this.onDeviceOrientationChange = this.onDeviceOrientationChange.bind(this);
+	    }
+	    static get instance() {
+	        Accelerator._instance = Accelerator._instance || new Accelerator(0);
+	        return Accelerator._instance;
+	    }
+	    on(type, caller, listener, args = null) {
+	        super.on(type, caller, listener, args);
+	        Laya.ILaya.Browser.window.addEventListener('devicemotion', this.onDeviceOrientationChange);
+	        return this;
+	    }
+	    off(type, caller, listener, onceOnly = false) {
+	        if (!this.hasListener(type))
+	            Laya.ILaya.Browser.window.removeEventListener('devicemotion', this.onDeviceOrientationChange);
+	        return super.off(type, caller, listener, onceOnly);
+	    }
+	    onDeviceOrientationChange(e) {
+	        var interval = e.interval;
+	        Accelerator.acceleration.x = e.acceleration.x;
+	        Accelerator.acceleration.y = e.acceleration.y;
+	        Accelerator.acceleration.z = e.acceleration.z;
+	        Accelerator.accelerationIncludingGravity.x = e.accelerationIncludingGravity.x;
+	        Accelerator.accelerationIncludingGravity.y = e.accelerationIncludingGravity.y;
+	        Accelerator.accelerationIncludingGravity.z = e.accelerationIncludingGravity.z;
+	        Accelerator.rotationRate.alpha = e.rotationRate.gamma * -1;
+	        Accelerator.rotationRate.beta = e.rotationRate.alpha * -1;
+	        Accelerator.rotationRate.gamma = e.rotationRate.beta;
+	        if (Laya.ILaya.Browser.onAndroid) {
+	            if (Laya.ILaya.Browser.userAgent.indexOf("Chrome") > -1) {
+	                Accelerator.rotationRate.alpha *= 180 / Math.PI;
+	                Accelerator.rotationRate.beta *= 180 / Math.PI;
+	                Accelerator.rotationRate.gamma *= 180 / Math.PI;
+	            }
+	            Accelerator.acceleration.x *= -1;
+	            Accelerator.accelerationIncludingGravity.x *= -1;
+	        }
+	        else if (Laya.ILaya.Browser.onIOS) {
+	            Accelerator.acceleration.y *= -1;
+	            Accelerator.acceleration.z *= -1;
+	            Accelerator.accelerationIncludingGravity.y *= -1;
+	            Accelerator.accelerationIncludingGravity.z *= -1;
+	            interval *= 1000;
+	        }
+	        this.event(Laya.Event.CHANGE, [Accelerator.acceleration, Accelerator.accelerationIncludingGravity, Accelerator.rotationRate, interval]);
+	    }
+	    static getTransformedAcceleration(acceleration) {
+	        Accelerator.transformedAcceleration = Accelerator.transformedAcceleration || new AccelerationInfo();
+	        Accelerator.transformedAcceleration.z = acceleration.z;
+	        if (Laya.ILaya.Browser.window.orientation == 90) {
+	            Accelerator.transformedAcceleration.x = acceleration.y;
+	            Accelerator.transformedAcceleration.y = -acceleration.x;
+	        }
+	        else if (Laya.ILaya.Browser.window.orientation == -90) {
+	            Accelerator.transformedAcceleration.x = -acceleration.y;
+	            Accelerator.transformedAcceleration.y = acceleration.x;
+	        }
+	        else if (!Laya.ILaya.Browser.window.orientation) {
+	            Accelerator.transformedAcceleration.x = acceleration.x;
+	            Accelerator.transformedAcceleration.y = acceleration.y;
+	        }
+	        else if (Laya.ILaya.Browser.window.orientation == 180) {
+	            Accelerator.transformedAcceleration.x = -acceleration.x;
+	            Accelerator.transformedAcceleration.y = -acceleration.y;
+	        }
+	        var tx;
+	        if (Laya.ILaya.stage.canvasDegree == -90) {
+	            tx = Accelerator.transformedAcceleration.x;
+	            Accelerator.transformedAcceleration.x = -Accelerator.transformedAcceleration.y;
+	            Accelerator.transformedAcceleration.y = tx;
+	        }
+	        else if (Laya.ILaya.stage.canvasDegree == 90) {
+	            tx = Accelerator.transformedAcceleration.x;
+	            Accelerator.transformedAcceleration.x = Accelerator.transformedAcceleration.y;
+	            Accelerator.transformedAcceleration.y = -tx;
+	        }
+	        return Accelerator.transformedAcceleration;
+	    }
+	}
+	Accelerator.acceleration = new AccelerationInfo();
+	Accelerator.accelerationIncludingGravity = new AccelerationInfo();
+	Accelerator.rotationRate = new RotationInfo();
+
+	class Shake extends Laya.EventDispatcher {
+	    constructor() {
+	        super();
+	    }
+	    static get instance() {
+	        Shake._instance = Shake._instance || new Shake();
+	        return Shake._instance;
+	    }
+	    start(throushold, interval) {
+	        this.throushold = throushold;
+	        this.shakeInterval = interval;
+	        this.lastX = this.lastY = this.lastZ = NaN;
+	        Accelerator.instance.on(Laya.Event.CHANGE, this, this.onShake);
+	    }
+	    stop() {
+	        Accelerator.instance.off(Laya.Event.CHANGE, this, this.onShake);
+	    }
+	    onShake(acceleration, accelerationIncludingGravity, rotationRate, interval) {
+	        if (isNaN(this.lastX)) {
+	            this.lastX = accelerationIncludingGravity.x;
+	            this.lastY = accelerationIncludingGravity.y;
+	            this.lastZ = accelerationIncludingGravity.z;
+	            this.lastMillSecond = Laya.ILaya.Browser.now();
+	            return;
+	        }
+	        var deltaX = Math.abs(this.lastX - accelerationIncludingGravity.x);
+	        var deltaY = Math.abs(this.lastY - accelerationIncludingGravity.y);
+	        var deltaZ = Math.abs(this.lastZ - accelerationIncludingGravity.z);
+	        if (this.isShaked(deltaX, deltaY, deltaZ)) {
+	            var deltaMillSecond = Laya.ILaya.Browser.now() - this.lastMillSecond;
+	            if (deltaMillSecond > this.shakeInterval) {
+	                this.event(Laya.Event.CHANGE);
+	                this.lastMillSecond = Laya.ILaya.Browser.now();
+	            }
+	        }
+	        this.lastX = accelerationIncludingGravity.x;
+	        this.lastY = accelerationIncludingGravity.y;
+	        this.lastZ = accelerationIncludingGravity.z;
+	    }
+	    isShaked(deltaX, deltaY, deltaZ) {
+	        return (deltaX > this.throushold && deltaY > this.throushold) ||
+	            (deltaX > this.throushold && deltaZ > this.throushold) ||
+	            (deltaY > this.throushold && deltaZ > this.throushold);
+	    }
+	}
+
+	class GeolocationInfo {
+	    setPosition(pos) {
+	        this.pos = pos;
+	        this.coords = pos.coords;
+	    }
+	    get latitude() {
+	        return this.coords.latitude;
+	    }
+	    get longitude() {
+	        return this.coords.longitude;
+	    }
+	    get altitude() {
+	        return this.coords.altitude;
+	    }
+	    get accuracy() {
+	        return this.coords.accuracy;
+	    }
+	    get altitudeAccuracy() {
+	        return this.coords.altitudeAccuracy;
+	    }
+	    get heading() {
+	        return this.coords.heading;
+	    }
+	    get speed() {
+	        return this.coords.speed;
+	    }
+	    get timestamp() {
+	        return this.pos.timestamp;
+	    }
+	}
+
+	class Geolocation {
+	    constructor() {
+	    }
+	    static getCurrentPosition(onSuccess, onError = null) {
+	        Geolocation.navigator.geolocation.getCurrentPosition(function (pos) {
+	            Geolocation.position.setPosition(pos);
+	            onSuccess.runWith(Geolocation.position);
+	        }, function (error) {
+	            onError.runWith(error);
+	        }, {
+	            enableHighAccuracy: Geolocation.enableHighAccuracy,
+	            timeout: Geolocation.timeout,
+	            maximumAge: Geolocation.maximumAge
+	        });
+	    }
+	    static watchPosition(onSuccess, onError) {
+	        return Geolocation.navigator.geolocation.watchPosition(function (pos) {
+	            Geolocation.position.setPosition(pos);
+	            onSuccess.runWith(Geolocation.position);
+	        }, function (error) {
+	            onError.runWith(error);
+	        }, {
+	            enableHighAccuracy: Geolocation.enableHighAccuracy,
+	            timeout: Geolocation.timeout,
+	            maximumAge: Geolocation.maximumAge
+	        });
+	    }
+	    static clearWatch(id) {
+	        Geolocation.navigator.geolocation.clearWatch(id);
+	    }
+	}
+	Geolocation.navigator = Laya.ILaya.Browser.window.navigator;
+	Geolocation.position = new GeolocationInfo();
+	Geolocation.PERMISSION_DENIED = 1;
+	Geolocation.POSITION_UNAVAILABLE = 2;
+	Geolocation.TIMEOUT = 3;
+	Geolocation.supported = !!Geolocation.navigator.geolocation;
+	Geolocation.enableHighAccuracy = false;
+	Geolocation.timeout = 1E10;
+	Geolocation.maximumAge = 0;
+
+	class HtmlVideo extends Laya.Bitmap {
+	    constructor() {
+	        super();
+	        this._width = 1;
+	        this._height = 1;
+	        this.createDomElement();
+	    }
+	    createDomElement() {
+	        this._source = this.video = Laya.ILaya.Browser.createElement("video");
+	        var style = this.video.style;
+	        style.position = 'absolute';
+	        style.top = '0px';
+	        style.left = '0px';
+	        this.video.addEventListener("loadedmetadata", (function () {
+	            this._w = this.video.videoWidth;
+	            this._h = this.video.videoHeight;
+	        })['bind'](this));
+	    }
+	    setSource(url, extension) {
+	        while (this.video.childElementCount)
+	            this.video.firstChild.remove();
+	        if (extension & 1)
+	            this.appendSource(url, "video/mp4");
+	        if (extension & 2)
+	            this.appendSource(url + ".ogg", "video/ogg");
+	    }
+	    appendSource(source, type) {
+	        var sourceElement = Laya.ILaya.Browser.createElement("source");
+	        sourceElement.src = source;
+	        sourceElement.type = type;
+	        this.video.appendChild(sourceElement);
+	    }
+	    getVideo() {
+	        return this.video;
+	    }
+	    _getSource() {
+	        return this._source;
+	    }
+	    destroy() {
+	        super.destroy();
+	        var isConchApp = Laya.ILaya.Render.isConchApp;
+	        if (isConchApp) {
+	            this.video._destroy();
+	        }
+	    }
+	}
+	HtmlVideo.create = function () {
+	    return new HtmlVideo();
+	};
+
+	class Media {
+	    constructor() {
+	    }
+	    static supported() {
+	        return !!Laya.ILaya.Browser.window.navigator.getUserMedia;
+	    }
+	    static getMedia(options, onSuccess, onError) {
+	        if (Laya.ILaya.Browser.window.navigator.getUserMedia) {
+	            Laya.ILaya.Browser.window.navigator.getUserMedia(options, function (stream) {
+	                onSuccess.runWith(Laya.ILaya.Browser.window.URL.createObjectURL(stream));
+	            }, function (err) {
+	                onError.runWith(err);
+	            });
+	        }
+	    }
+	}
+
+	class WebGLVideo extends HtmlVideo {
+	    constructor() {
+	        super();
+	        var gl = Laya.LayaGL.instance;
+	        if (!Laya.ILaya.Render.isConchApp && Laya.ILaya.Browser.onIPhone)
+	            return;
+	        this.gl = Laya.ILaya.Render.isConchApp ? window.LayaGLContext.instance : Laya.WebGLContext.mainContext;
+	        this._source = this.gl.createTexture();
+	        Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, this._source);
+	        this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+	        this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+	        this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+	        this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+	        Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, null);
+	    }
+	    updateTexture() {
+	        if (!Laya.ILaya.Render.isConchApp && Laya.ILaya.Browser.onIPhone)
+	            return;
+	        var gl = Laya.LayaGL.instance;
+	        Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, this._source);
+	        this.gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.video);
+	        WebGLVideo.curBindSource = this._source;
+	    }
+	    get _glTexture() {
+	        return this._source;
+	    }
+	    destroy() {
+	        if (this._source) {
+	            this.gl = Laya.ILaya.Render.isConchApp ? window.LayaGLContext.instance : Laya.WebGLContext.mainContext;
+	            if (WebGLVideo.curBindSource == this._source) {
+	                Laya.WebGLContext.bindTexture(this.gl, this.gl.TEXTURE_2D, null);
+	                WebGLVideo.curBindSource = null;
+	            }
+	            this.gl.deleteTexture(this._source);
+	        }
+	        super.destroy();
+	    }
+	}
+
+	class Video extends Laya.Sprite {
+	    constructor(width = 320, height = 240) {
+	        super();
+	        this.htmlVideo = new WebGLVideo();
+	        this.videoElement = this.htmlVideo.getVideo();
+	        this.videoElement.layaTarget = this;
+	        this.internalTexture = new Laya.Texture(this.htmlVideo);
+	        this.videoElement.addEventListener("abort", Video.onAbort);
+	        this.videoElement.addEventListener("canplay", Video.onCanplay);
+	        this.videoElement.addEventListener("canplaythrough", Video.onCanplaythrough);
+	        this.videoElement.addEventListener("durationchange", Video.onDurationchange);
+	        this.videoElement.addEventListener("emptied", Video.onEmptied);
+	        this.videoElement.addEventListener("error", Video.onError);
+	        this.videoElement.addEventListener("loadeddata", Video.onLoadeddata);
+	        this.videoElement.addEventListener("loadedmetadata", Video.onLoadedmetadata);
+	        this.videoElement.addEventListener("loadstart", Video.onLoadstart);
+	        this.videoElement.addEventListener("pause", Video.onPause);
+	        this.videoElement.addEventListener("play", Video.onPlay);
+	        this.videoElement.addEventListener("playing", Video.onPlaying);
+	        this.videoElement.addEventListener("progress", Video.onProgress);
+	        this.videoElement.addEventListener("ratechange", Video.onRatechange);
+	        this.videoElement.addEventListener("seeked", Video.onSeeked);
+	        this.videoElement.addEventListener("seeking", Video.onSeeking);
+	        this.videoElement.addEventListener("stalled", Video.onStalled);
+	        this.videoElement.addEventListener("suspend", Video.onSuspend);
+	        this.videoElement.addEventListener("timeupdate", Video.onTimeupdate);
+	        this.videoElement.addEventListener("volumechange", Video.onVolumechange);
+	        this.videoElement.addEventListener("waiting", Video.onWaiting);
+	        this.videoElement.addEventListener("ended", this.onPlayComplete['bind'](this));
+	        this.size(width, height);
+	        if (Laya.ILaya.Browser.onMobile) {
+	            this.onDocumentClick = this.onDocumentClick.bind(this);
+	            Laya.ILaya.Browser.document.addEventListener("touchend", this.onDocumentClick);
+	        }
+	    }
+	    static onAbort(e) { e.target.layaTarget.event("abort"); }
+	    static onCanplay(e) { e.target.layaTarget.event("canplay"); }
+	    static onCanplaythrough(e) { e.target.layaTarget.event("canplaythrough"); }
+	    static onDurationchange(e) { e.target.layaTarget.event("durationchange"); }
+	    static onEmptied(e) { e.target.layaTarget.event("emptied"); }
+	    static onError(e) { e.target.layaTarget.event("error"); }
+	    static onLoadeddata(e) { e.target.layaTarget.event("loadeddata"); }
+	    static onLoadedmetadata(e) { e.target.layaTarget.event("loadedmetadata"); }
+	    static onLoadstart(e) { e.target.layaTarget.event("loadstart"); }
+	    static onPause(e) { e.target.layaTarget.event("pause"); }
+	    static onPlay(e) { e.target.layaTarget.event("play"); }
+	    static onPlaying(e) { e.target.layaTarget.event("playing"); }
+	    static onProgress(e) { e.target.layaTarget.event("progress"); }
+	    static onRatechange(e) { e.target.layaTarget.event("ratechange"); }
+	    static onSeeked(e) { e.target.layaTarget.event("seeked"); }
+	    static onSeeking(e) { e.target.layaTarget.event("seeking"); }
+	    static onStalled(e) { e.target.layaTarget.event("stalled"); }
+	    static onSuspend(e) { e.target.layaTarget.event("suspend"); }
+	    static onTimeupdate(e) { e.target.layaTarget.event("timeupdate"); }
+	    static onVolumechange(e) { e.target.layaTarget.event("volumechange"); }
+	    static onWaiting(e) { e.target.layaTarget.event("waiting"); }
+	    onPlayComplete(e) {
+	        this.event("ended");
+	        if (!Laya.ILaya.Render.isConchApp || !this.videoElement || !this.videoElement.loop)
+	            Laya.ILaya.timer.clear(this, this.renderCanvas);
+	    }
+	    load(url) {
+	        if (url.indexOf("blob:") == 0)
+	            this.videoElement.src = url;
+	        else
+	            this.htmlVideo.setSource(url, 1);
+	    }
+	    play() {
+	        this.videoElement.play();
+	        Laya.ILaya.timer.frameLoop(1, this, this.renderCanvas);
+	    }
+	    pause() {
+	        this.videoElement.pause();
+	        Laya.ILaya.timer.clear(this, this.renderCanvas);
+	    }
+	    reload() {
+	        this.videoElement.load();
+	    }
+	    canPlayType(type) {
+	        var typeString;
+	        switch (type) {
+	            case 1:
+	                typeString = "video/mp4";
+	                break;
+	            case 2:
+	                typeString = "video/ogg";
+	                break;
+	            case 8:
+	                typeString = "video/webm";
+	                break;
+	        }
+	        return this.videoElement.canPlayType(typeString);
+	    }
+	    renderCanvas() {
+	        if (this.readyState === 0)
+	            return;
+	        this.htmlVideo['updateTexture']();
+	        this.graphics.clear();
+	        this.graphics.drawTexture(this.internalTexture, 0, 0, this.width, this.height);
+	    }
+	    onDocumentClick() {
+	        this.videoElement.play();
+	        this.videoElement.pause();
+	        Laya.ILaya.Browser.document.removeEventListener("touchend", this.onDocumentClick);
+	    }
+	    get buffered() {
+	        return this.videoElement.buffered;
+	    }
+	    get currentSrc() {
+	        return this.videoElement.currentSrc;
+	    }
+	    get currentTime() {
+	        return this.videoElement.currentTime;
+	    }
+	    set currentTime(value) {
+	        this.videoElement.currentTime = value;
+	        this.renderCanvas();
+	    }
+	    set volume(value) {
+	        this.videoElement.volume = value;
+	    }
+	    get volume() {
+	        return this.videoElement.volume;
+	    }
+	    get readyState() {
+	        return this.videoElement.readyState;
+	    }
+	    get videoWidth() {
+	        return this.videoElement.videoWidth;
+	    }
+	    get videoHeight() {
+	        return this.videoElement.videoHeight;
+	    }
+	    get duration() {
+	        return this.videoElement.duration;
+	    }
+	    get ended() {
+	        return this.videoElement.ended;
+	    }
+	    get error() {
+	        return this.videoElement.error;
+	    }
+	    get loop() {
+	        return this.videoElement.loop;
+	    }
+	    set loop(value) {
+	        this.videoElement.loop = value;
+	    }
+	    set x(val) {
+	        super.x = val;
+	        if (Laya.ILaya.Render.isConchApp) {
+	            var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
+	            this.videoElement.style.left = transform.x;
+	        }
+	    }
+	    get x() {
+	        return super.x;
+	    }
+	    set y(val) {
+	        super.y = val;
+	        if (Laya.ILaya.Render.isConchApp) {
+	            var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
+	            this.videoElement.style.top = transform.y;
+	        }
+	    }
+	    get y() {
+	        return super.y;
+	    }
+	    get playbackRate() {
+	        return this.videoElement.playbackRate;
+	    }
+	    set playbackRate(value) {
+	        this.videoElement.playbackRate = value;
+	    }
+	    get muted() {
+	        return this.videoElement.muted;
+	    }
+	    set muted(value) {
+	        this.videoElement.muted = value;
+	    }
+	    get paused() {
+	        return this.videoElement.paused;
+	    }
+	    get preload() {
+	        return this.videoElement.preload;
+	    }
+	    set preload(value) {
+	        this.videoElement.preload = value;
+	    }
+	    get seekable() {
+	        return this.videoElement.seekable;
+	    }
+	    get seeking() {
+	        return this.videoElement.seeking;
+	    }
+	    size(width, height) {
+	        super.size(width, height);
+	        if (Laya.ILaya.Render.isConchApp) {
+	            var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
+	            this.videoElement.width = width * transform.scaleX;
+	        }
+	        else {
+	            this.videoElement.width = width / Laya.ILaya.Browser.pixelRatio;
+	        }
+	        if (this.paused)
+	            this.renderCanvas();
+	        return this;
+	    }
+	    set width(value) {
+	        if (Laya.ILaya.Render.isConchApp) {
+	            var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
+	            this.videoElement.width = value * transform.scaleX;
+	        }
+	        else {
+	            this.videoElement.width = this.width / Laya.ILaya.Browser.pixelRatio;
+	        }
+	        super.width = value;
+	        if (this.paused)
+	            this.renderCanvas();
+	    }
+	    get width() {
+	        return super.width;
+	    }
+	    set height(value) {
+	        if (Laya.ILaya.Render.isConchApp) {
+	            var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
+	            this.videoElement.height = value * transform.scaleY;
+	        }
+	        else {
+	            this.videoElement.height = this.height / Laya.ILaya.Browser.pixelRatio;
+	        }
+	        super.height = value;
+	    }
+	    get height() {
+	        return super.height;
+	    }
+	    destroy(detroyChildren = true) {
+	        super.destroy(detroyChildren);
+	        this.videoElement.removeEventListener("abort", Video.onAbort);
+	        this.videoElement.removeEventListener("canplay", Video.onCanplay);
+	        this.videoElement.removeEventListener("canplaythrough", Video.onCanplaythrough);
+	        this.videoElement.removeEventListener("durationchange", Video.onDurationchange);
+	        this.videoElement.removeEventListener("emptied", Video.onEmptied);
+	        this.videoElement.removeEventListener("error", Video.onError);
+	        this.videoElement.removeEventListener("loadeddata", Video.onLoadeddata);
+	        this.videoElement.removeEventListener("loadedmetadata", Video.onLoadedmetadata);
+	        this.videoElement.removeEventListener("loadstart", Video.onLoadstart);
+	        this.videoElement.removeEventListener("pause", Video.onPause);
+	        this.videoElement.removeEventListener("play", Video.onPlay);
+	        this.videoElement.removeEventListener("playing", Video.onPlaying);
+	        this.videoElement.removeEventListener("progress", Video.onProgress);
+	        this.videoElement.removeEventListener("ratechange", Video.onRatechange);
+	        this.videoElement.removeEventListener("seeked", Video.onSeeked);
+	        this.videoElement.removeEventListener("seeking", Video.onSeeking);
+	        this.videoElement.removeEventListener("stalled", Video.onStalled);
+	        this.videoElement.removeEventListener("suspend", Video.onSuspend);
+	        this.videoElement.removeEventListener("timeupdate", Video.onTimeupdate);
+	        this.videoElement.removeEventListener("volumechange", Video.onVolumechange);
+	        this.videoElement.removeEventListener("waiting", Video.onWaiting);
+	        this.videoElement.removeEventListener("ended", this.onPlayComplete);
+	        this.pause();
+	        this.videoElement.layaTarget = null;
+	        this.videoElement = null;
+	        this.htmlVideo.destroy();
+	    }
+	    syncVideoPosition() {
+	        var stage = Laya.ILaya.stage;
+	        var rec;
+	        rec = Laya.ILaya.Utils.getGlobalPosAndScale(this);
+	        var a = stage._canvasTransform.a, d = stage._canvasTransform.d;
+	        var x = rec.x * stage.clientScaleX * a + stage.offset.x;
+	        var y = rec.y * stage.clientScaleY * d + stage.offset.y;
+	        this.videoElement.style.left = x + 'px';
+	        this.videoElement.style.top = y + 'px';
+	        this.videoElement.width = this.width / Laya.ILaya.Browser.pixelRatio;
+	        this.videoElement.height = this.height / Laya.ILaya.Browser.pixelRatio;
+	    }
+	}
+	Video.MP4 = 1;
+	Video.OGG = 2;
+	Video.CAMERA = 4;
+	Video.WEBM = 8;
+	Video.SUPPORT_PROBABLY = "probably";
+	Video.SUPPORT_MAYBY = "maybe";
+	Video.SUPPORT_NO = "";
+
+	class Gyroscope extends Laya.EventDispatcher {
+	    constructor(singleton) {
+	        super();
+	        this.onDeviceOrientationChange = this.onDeviceOrientationChange.bind(this);
+	    }
+	    static get instance() {
+	        Gyroscope._instance = Gyroscope._instance || new Gyroscope(0);
+	        return Gyroscope._instance;
+	    }
+	    on(type, caller, listener, args = null) {
+	        super.on(type, caller, listener, args);
+	        Laya.ILaya.Browser.window.addEventListener('deviceorientation', this.onDeviceOrientationChange);
+	        return this;
+	    }
+	    off(type, caller, listener, onceOnly = false) {
+	        if (!this.hasListener(type))
+	            Laya.ILaya.Browser.window.removeEventListener('deviceorientation', this.onDeviceOrientationChange);
+	        return super.off(type, caller, listener, onceOnly);
+	    }
+	    onDeviceOrientationChange(e) {
+	        Gyroscope.info.alpha = e.alpha;
+	        Gyroscope.info.beta = e.beta;
+	        Gyroscope.info.gamma = e.gamma;
+	        if (e.webkitCompassHeading) {
+	            Gyroscope.info.alpha = e.webkitCompassHeading * -1;
+	            Gyroscope.info.compassAccuracy = e.webkitCompassAccuracy;
+	        }
+	        this.event(Laya.Event.CHANGE, [e.absolute, Gyroscope.info]);
+	    }
+	}
+	Gyroscope.info = new RotationInfo();
+
+	exports.AccelerationInfo = AccelerationInfo;
+	exports.Accelerator = Accelerator;
+	exports.Geolocation = Geolocation;
+	exports.GeolocationInfo = GeolocationInfo;
+	exports.Gyroscope = Gyroscope;
+	exports.HtmlVideo = HtmlVideo;
+	exports.Media = Media;
+	exports.RotationInfo = RotationInfo;
+	exports.Shake = Shake;
+	exports.Video = Video;
+	exports.WebGLVideo = WebGLVideo;
+
+}(window.Laya = window.Laya|| {}, Laya));

ファイルの差分が大きいため隠しています
+ 1528 - 0
bin/libs/laya.html.js


ファイルの差分が大きいため隠しています
+ 633 - 0
bin/libs/laya.particle.js


ファイルの差分が大きいため隠しています
+ 2037 - 0
bin/libs/laya.pathfinding.js


ファイルの差分が大きいため隠しています
+ 3196 - 0
bin/libs/laya.physics.js


ファイルの差分が大きいため隠しています
+ 691 - 0
bin/libs/laya.physics3D.js


ファイルの差分が大きいため隠しています
+ 380 - 0
bin/libs/laya.physics3D.runtime.js


ファイルの差分が大きいため隠しています
+ 646 - 0
bin/libs/laya.physics3D.wasm.js


ファイルの差分が大きいため隠しています
+ 1690 - 0
bin/libs/laya.qqmini.js


ファイルの差分が大きいため隠しています
+ 1668 - 0
bin/libs/laya.quickgamemini.js


ファイルの差分が大きいため隠しています
+ 1604 - 0
bin/libs/laya.tiledmap.js


ファイルの差分が大きいため隠しています
+ 6069 - 0
bin/libs/laya.ui.js


ファイルの差分が大きいため隠しています
+ 1673 - 0
bin/libs/laya.vvmini.js


ファイルの差分が大きいため隠しています
+ 1689 - 0
bin/libs/laya.wxmini.js


ファイルの差分が大きいため隠しています
+ 1677 - 0
bin/libs/laya.xmmini.js


ファイルの差分が大きいため隠しています
+ 1 - 0
bin/libs/worker.js


+ 132 - 0
bin/libs/workerloader.js

@@ -0,0 +1,132 @@
+var createImageBitmapOK=self.createImageBitmap?true:false;
+onmessage =function (evt){
+  
+  var data = evt.data;//通过evt.data获得发送来的数据
+  loadImage2(data);
+  if(!isSet)
+  {
+	  isSet=true;
+	  setInterval(workerloop,1000);
+   }
+}
+var isSet=true;
+function workerloop()
+{
+	myTrace("png:workerloop");
+}
+
+
+var enableTrace=false;
+var ifShowTraceToMain=false;
+function myTrace(msg)
+{
+	if(!enableTrace) return;
+	console.log("png:"+msg)
+	if(ifShowTraceToMain)
+	{
+		showMsgToMain(msg);
+	}
+}
+function loadImage2(url)
+{
+	var xhr,
+    _this = this;
+	var failed=false;
+      xhr = new XMLHttpRequest;
+      xhr.open("GET", url, true);
+	  //showMsgToMain("loadImage2");
+	  xhr.responseType = "arraybuffer";
+      myTrace("load:"+url);
+      xhr.onload = function() {
+		var response=xhr.response || xhr.mozResponseArrayBuffer;
+		//showMsgToMain("onload:");
+		myTrace("onload:"+url);
+		if((xhr.status != 200&&xhr.status!=0)||response.byteLength<10)
+		{
+			if(!failed)
+			{
+				failed=true;
+				pngFail(url,"loadFail from onload"+xhr.status);
+			}
+			
+			return;
+		}
+        var data, png;
+        data = new Uint8Array(response);
+		doCreateImageBitmap(data,url);
+        
+      };
+	  xhr.onerror = function(e){
+		pngFail(url,"loadFail");
+	}
+
+      xhr.send(null);
+}
+function doCreateImageBitmap(response,url)
+{
+	try
+	{
+		//showMsgToMain("hihidoCreateImageBitmap");
+		//showMsgToMain("doCreateImageBitmap:"+response);
+		//var startTime=getTimeNow();
+		//showMsgToMain("new self.Blob");
+		var startTime=getTimeNow();
+		
+		response = new self.Blob([response],{type:"image/png"});
+		self.createImageBitmap(response).then(function(imageBitmap) {
+			//showMsgToMain("imageBitmapCreated:");
+			var data={};
+	        data.url=url;
+			data.imageBitmap=imageBitmap;
+			data.dataType="imageBitmap";
+			
+			data.startTime=startTime;
+	        data.decodeTime=getTimeNow()-startTime;
+			data.sendTime=getTimeNow();
+			
+			myTrace("png:Decode By createImageBitmap,"+data.decodeTime,url);
+			
+			data.type="Image";
+			postMessage(data,[data.imageBitmap]);
+        }).catch(
+		function(e)
+		{
+			showMsgToMain("catch e:"+e);
+			pngFail(url,"parse fail"+e+":ya");
+		}
+		)
+	}catch(e)
+	{
+		pngFail(url,"parse fail"+e.toString()+":ya");
+	}
+}
+function getTimeNow()
+{
+	return new Date().getTime();
+}
+function disableWorker(msg)
+{
+	var data={};
+	data.url=url;
+	data.imagedata=null;
+	data.type="Disable";
+	data.msg=msg;
+	postMessage(data);
+}
+function pngFail(url,msg)
+{
+	var data={};
+	data.url=url;
+	data.imagedata=null;
+	data.type="Image";
+	data.msg=msg;
+	console.log("png:"+msg+" "+url);
+	postMessage(data);
+}
+function showMsgToMain(msg)
+{
+	var data={};
+	data.type="Msg";
+	data.msg=msg;
+	postMessage(data);
+}

+ 40 - 0
bin/res/atlas/.rec

@@ -0,0 +1,40 @@
+D .
+D comp
+P 316AD948 btn_close.png
+P 5B258D17 button.png
+P 3C493DD4 check_circle.png
+P 98E54F0D checkbox.png
+P 6B7AB858 clip_num.png
+P 63A22FAC clip_tree_arrow.png
+P D749C312 clip_tree_folder.png
+P 704C5D70 combobox.png
+P D566AE8B fontClip.png
+P 38AB8F3F fontClip_num.png
+P 6EF336AE hscroll$bar.png
+P 7FF47AC5 hscroll$down.png
+P 3D7B147A hscroll$up.png
+P 750BD445 hscroll.png
+P 9A5EF899 hslider$bar.png
+P 9CED7132 hslider.png
+P BA2A0579 html.png
+P 8236CD48 image.png
+P 4ACB7AEF img_bg.png
+P FCD04607 img_bg2.png
+P 23FB4D29 img_bg3.png
+P 5FD17798 img_bg4.png
+P 2BE22124 img_bg5.png
+P BA28BD65 img_blank.png
+P BA2A0579 label.png
+P B017E53E progress$bar.png
+P C05839CD progress.png
+P 3C493DD4 radio.png
+P 3C493DD4 radiogroup.png
+P 5BA25C15 tab.png
+P A3D7A036 textarea.png
+P A3D7A036 textinput.png
+P 2DCE1DF9 vscroll$bar.png
+P 6FE7EA34 vscroll$down.png
+P 0587871F vscroll$up.png
+P 5FD17798 vscroll.png
+P DDDDFB9E vslider$bar.png
+P 01BAE7F5 vslider.png

ファイルの差分が大きいため隠しています
+ 1 - 0
bin/res/atlas/comp.atlas


BIN
bin/res/atlas/comp.png


+ 1 - 0
bin/version.json

@@ -0,0 +1 @@
+{}

+ 53 - 0
laya/.laya

@@ -0,0 +1,53 @@
+<project version="2.0">
+   <asynRes>img,temp,sound                                    </asynRes>
+   <unDealRes>embed                                    </unDealRes>
+   <resTypes>png,jpg   </resTypes>
+   <resExportPath>bin/res/atlas   </resExportPath>
+   <asynResExportPath>bin   </asynResExportPath>
+   <codeExportPath>src/ui   </codeExportPath>
+   <codeImports><![CDATA[import laya.ui.*;]]>   </codeImports>
+   <codeImportsJS><![CDATA[var View=laya.ui.View;
+var Dialog=laya.ui.Dialog;]]>   </codeImportsJS>
+   <uiType>0   </uiType>
+   <uiExportPath>bin/ui.json   </uiExportPath>
+   <boxTypes>Sprite,Box,List,Tab,RadioGroup,ViewStack,Panel,HBox,VBox,Tree   </boxTypes>
+   <pageTypes>Scene,View,Dialog   </pageTypes>
+   <shareResPath/>
+   <codeType>1   </codeType>
+   <resCanCompress/>
+   <resPublishQuality>80                                    </resPublishQuality>
+   <langPath/>
+   <defaultFont/>
+   <codeImportsTS><![CDATA[import View=Laya.View;
+import Dialog=Laya.Dialog;
+import Scene=Laya.Scene;]]>   </codeImportsTS>
+   <textureWidth>2048   </textureWidth>
+   <textureHeight>2048   </textureHeight>
+   <picWidth>512   </picWidth>
+   <picHeight>512   </picHeight>
+   <power2>false   </power2>
+   <trimempty>true   </trimempty>
+   <startScene/>
+   <engineType>2D   </engineType>
+   <scaleMode>fixedwidth   </scaleMode>
+   <screenMode>none   </screenMode>
+   <alignV>top   </alignV>
+   <alignH>left   </alignH>
+   <designWidth>720   </designWidth>
+   <designHeight>1280   </designHeight>
+   <codeViewExportPath>src/view   </codeViewExportPath>
+   <picType>0   </picType>
+   <atlasType>1   </atlasType>
+   <atlasScale/>
+   <debugMode>false   </debugMode>
+   <copyRes>true   </copyRes>
+   <dataCompact>true   </dataCompact>
+   <isRemoteProject>false   </isRemoteProject>
+   <idePath/>
+   <ver>2.0   </ver>
+   <stat>false   </stat>
+   <physicsDebug>false   </physicsDebug>
+   <toJsonScene>true   </toJsonScene>
+   <compressTexture>false   </compressTexture>
+   <libProjectPath/>
+</project>

BIN
laya/assets/game/-10.png


BIN
laya/assets/game/-11.png


BIN
laya/assets/game/-7.png


BIN
laya/assets/game/-9.png


BIN
laya/assets/game/1.png


BIN
laya/assets/game/2.png


BIN
laya/assets/game/3.png


BIN
laya/assets/game/4.png


BIN
laya/assets/game/5.png


BIN
laya/assets/game/6.png


BIN
laya/assets/game/bg.png


+ 1 - 0
laya/ignore.cfg

@@ -0,0 +1 @@
+{"src/Main.ts":true,"src/GameConfig.ts":true,"src/ui":true}

+ 318 - 0
laya/pages/Main1.scene

@@ -0,0 +1,318 @@
+{
+    "x":0,
+    "type":"Scene",
+    "selectedBox":33,
+    "selecteID":37,
+    "searchKey":"Scene",
+    "props":{"width":720,"sceneColor":"#000000","height":1280},
+    "nodeParent":-1,
+    "maxID":51,
+    "label":"Scene",
+    "isOpen":true,
+    "isDirectory":true,
+    "isAniNode":true,
+    "hasChild":true,
+    "compId":2,
+    "child":[
+        {
+            "x":15,
+            "type":"Image",
+            "searchKey":"Image,BG",
+            "props":{"top":0,"skin":"game/bg.png","sizeGrid":"12,13,17,13","right":0,"name":"BG","left":0,"bottom":0},
+            "nodeParent":2,
+            "label":"BG",
+            "isDirectory":false,
+            "isAniNode":true,
+            "hasChild":false,
+            "compId":29,
+            "child":[
+                ]
+        },
+        {
+            "x":15,
+            "type":"Box",
+            "searchKey":"Box",
+            "props":{"y":381,"x":360,"width":720,"height":600,"anchorY":0.5,"anchorX":0.5},
+            "nodeParent":2,
+            "label":"Box",
+            "isOpen":true,
+            "isDirectory":true,
+            "isAniNode":true,
+            "hasChild":true,
+            "compId":33,
+            "child":[
+                {
+                    "x":30,
+                    "type":"Image",
+                    "searchKey":"Image,move1",
+                    "props":{"y":151,"x":297,"width":554,"skin":"game/-7.png","rotation":180,"pivotY":39,"pivotX":277,"name":"move1","height":77},
+                    "nodeParent":33,
+                    "label":"move1",
+                    "isOpen":false,
+                    "isDirectory":true,
+                    "isAniNode":true,
+                    "hasChild":true,
+                    "compId":34,
+                    "child":[
+                        {
+                            "type":"ChainCollider",
+                            "switchAble":true,
+                            "searchKey":"ChainCollider",
+                            "removeAble":true,
+                            "props":{"points":"481,44,0,45,-1,31,58,31,480,31"},
+                            "nodeParent":34,
+                            "label":"ChainCollider",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":45,
+                            "child":[
+                                ]
+                        },
+                        {
+                            "type":"RigidBody",
+                            "switchAble":true,
+                            "searchKey":"RigidBody",
+                            "removeAble":true,
+                            "props":{},
+                            "nodeParent":34,
+                            "label":"RigidBody",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":46,
+                            "child":[
+                                ]
+                        }]
+                },
+                {
+                    "x":30,
+                    "type":"Image",
+                    "searchKey":"Image,move2",
+                    "props":{"y":385,"x":478,"width":328,"skin":"game/-7.png","sizeGrid":"32,217,36,109","scaleY":1,"scaleX":1,"rotation":45,"pivotY":39,"pivotX":175,"name":"move2","height":77},
+                    "nodeParent":33,
+                    "label":"move2",
+                    "isOpen":false,
+                    "isDirectory":true,
+                    "isAniNode":true,
+                    "hasChild":true,
+                    "compId":35,
+                    "child":[
+                        {
+                            "type":"ChainCollider",
+                            "switchAble":true,
+                            "searchKey":"ChainCollider",
+                            "removeAble":true,
+                            "props":{"points":"259,45,80,45,-1,45,-1,30,59,31,256,30"},
+                            "nodeParent":35,
+                            "label":"ChainCollider",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":47,
+                            "child":[
+                                ]
+                        },
+                        {
+                            "type":"RigidBody",
+                            "switchAble":true,
+                            "searchKey":"RigidBody",
+                            "removeAble":true,
+                            "props":{},
+                            "nodeParent":35,
+                            "label":"RigidBody",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":48,
+                            "child":[
+                                ]
+                        }]
+                },
+                {
+                    "x":30,
+                    "type":"Image",
+                    "searchKey":"Image,move3",
+                    "props":{"y":385,"x":226,"width":328,"skin":"game/-7.png","sizeGrid":"32,217,36,109","scaleY":1,"scaleX":1,"rotation":135,"pivotY":39,"pivotX":175,"name":"move3","height":77},
+                    "nodeParent":33,
+                    "label":"move3",
+                    "isOpen":false,
+                    "isDirectory":true,
+                    "isAniNode":true,
+                    "hasChild":true,
+                    "compId":37,
+                    "child":[
+                        {
+                            "type":"ChainCollider",
+                            "switchAble":true,
+                            "searchKey":"ChainCollider",
+                            "removeAble":true,
+                            "props":{"points":"255,45,-2,44,-1,30,254,30"},
+                            "nodeParent":37,
+                            "label":"ChainCollider",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":49,
+                            "child":[
+                                ]
+                        },
+                        {
+                            "type":"RigidBody",
+                            "switchAble":true,
+                            "searchKey":"RigidBody",
+                            "removeAble":true,
+                            "props":{},
+                            "nodeParent":37,
+                            "label":"RigidBody",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":50,
+                            "child":[
+                                ]
+                        }]
+                },
+                {
+                    "x":30,
+                    "type":"Image",
+                    "searchKey":"Image,right",
+                    "props":{"y":300,"x":360,"width":242,"skin":"game/-11.png","pivotY":259,"name":"right","height":518},
+                    "nodeParent":33,
+                    "label":"right",
+                    "isOpen":false,
+                    "isDirectory":true,
+                    "isAniNode":true,
+                    "hasChild":true,
+                    "compId":31,
+                    "child":[
+                        {
+                            "type":"ChainCollider",
+                            "switchAble":true,
+                            "searchKey":"ChainCollider",
+                            "removeAble":true,
+                            "props":{"points":"1,17,95,17,134,29,179,59,212,105,225,155,224,197,211,239,188,276,156,303,64,363,45,409,45,521"},
+                            "nodeParent":31,
+                            "label":"ChainCollider",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":41,
+                            "child":[
+                                ]
+                        },
+                        {
+                            "type":"RigidBody",
+                            "switchAble":true,
+                            "searchKey":"RigidBody",
+                            "removeAble":true,
+                            "props":{},
+                            "nodeParent":31,
+                            "label":"RigidBody",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":42,
+                            "child":[
+                                ]
+                        }]
+                },
+                {
+                    "x":30,
+                    "type":"Image",
+                    "searchKey":"Image,left",
+                    "props":{"y":300,"x":360,"width":243,"skin":"game/-10.png","pivotY":259,"pivotX":243,"name":"left","height":518},
+                    "nodeParent":33,
+                    "label":"left",
+                    "isOpen":false,
+                    "isDirectory":true,
+                    "isAniNode":true,
+                    "hasChild":true,
+                    "compId":32,
+                    "child":[
+                        {
+                            "type":"ChainCollider",
+                            "switchAble":true,
+                            "searchKey":"ChainCollider",
+                            "removeAble":true,
+                            "props":{"points":"197,522,196,411,183,372,155,348,102,315,55,279,27,233,16,194,16,149,33,100,52,71,78,48,112,27,147,17,246,17"},
+                            "nodeParent":32,
+                            "label":"ChainCollider",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":39,
+                            "child":[
+                                ]
+                        },
+                        {
+                            "type":"RigidBody",
+                            "switchAble":true,
+                            "searchKey":"RigidBody",
+                            "removeAble":true,
+                            "props":{},
+                            "nodeParent":32,
+                            "label":"RigidBody",
+                            "isDirectory":false,
+                            "isAniNode":true,
+                            "hasChild":false,
+                            "compId":40,
+                            "child":[
+                                ]
+                        }]
+                }]
+        },
+        {
+            "x":15,
+            "type":"Image",
+            "searchKey":"Image,Vase",
+            "props":{"y":934,"x":360,"skin":"game/-9.png","name":"Vase","anchorY":0.5,"anchorX":0.5},
+            "nodeParent":2,
+            "label":"Vase",
+            "isOpen":false,
+            "isDirectory":true,
+            "isAniNode":true,
+            "hasChild":true,
+            "compId":38,
+            "child":[
+                {
+                    "type":"ChainCollider",
+                    "switchAble":true,
+                    "searchKey":"ChainCollider",
+                    "removeAble":true,
+                    "props":{"points":"334,6,254,7,255,52,306,62,335,87,357,133,357,176,326,229,282,271,188,368,125,302,55,238,15,174,27,105,53,74,80,60,123,56,122,7,50,7"},
+                    "nodeParent":38,
+                    "label":"ChainCollider",
+                    "isDirectory":false,
+                    "isAniNode":true,
+                    "hasChild":false,
+                    "compId":43,
+                    "child":[
+                        ]
+                },
+                {
+                    "type":"RigidBody",
+                    "switchAble":true,
+                    "searchKey":"RigidBody",
+                    "removeAble":true,
+                    "props":{},
+                    "nodeParent":38,
+                    "label":"RigidBody",
+                    "isDirectory":false,
+                    "isAniNode":true,
+                    "hasChild":false,
+                    "compId":44,
+                    "child":[
+                        ]
+                }]
+        }],
+    "animations":[
+        {
+            "nodes":[
+                ],
+            "name":"ani1",
+            "id":1,
+            "frameRate":24,
+            "action":0
+        }]
+}

ファイルの差分が大きいため隠しています
+ 1 - 0
laya/pages/Prefab_Ball/ball1.prefab


ファイルの差分が大きいため隠しています
+ 1 - 0
laya/pages/Prefab_Ball/ball2.prefab


ファイルの差分が大きいため隠しています
+ 1 - 0
laya/pages/Prefab_Ball/ball3.prefab


ファイルの差分が大きいため隠しています
+ 1 - 0
laya/pages/Prefab_Ball/ball4.prefab


ファイルの差分が大きいため隠しています
+ 1 - 0
laya/pages/Prefab_Ball/ball5.prefab


ファイルの差分が大きいため隠しています
+ 1 - 0
laya/pages/Prefab_Ball/ball6.prefab


ファイルの差分が大きいため隠しています
+ 49305 - 0
libs/LayaAir.d.ts


+ 484 - 0
libs/layaAir.minigame.d.ts

@@ -0,0 +1,484 @@
+declare module laya.wx.mini {
+    import Handler = laya.utils.Handler;
+    class MiniAdpter {
+        static EnvConfig: any;
+        /**全局window对象**/
+        static window: any;
+        static systemInfo: any;
+        static isZiYu: boolean;
+        static isPosMsgYu: boolean;
+        /**是否自动缓存下载的图片跟声音文件,默认为true**/
+        static autoCacheFile: boolean;
+        /**50M缓存容量满时每次清理容量值,默认每次清理5M**/
+        static minClearSize: number;
+        /**本地资源列表**/
+        static nativefiles: Array<any>;
+        /**本地分包资源表**/
+        static subNativeFiles: any;
+        /**本地分包文件目录数组**/
+        static subNativeheads: Array<any>;
+        /**本地分包文件目录映射表**/
+        static subMaps: Array<any>;
+        static AutoCacheDownFile: boolean;
+        static getJson(data: string): any;
+        /**激活微信小游戏适配器*/
+        static enable(): void;
+        /**
+         * 初始化回调
+         * @param isPosMsg 是否需要在主域中自动将加载的文本数据自动传递到子域,默认 false
+         * @param isSon 是否是子域,默认为false
+         */
+        static init(isPosMsg?: boolean, isSon?: boolean): void;
+        /**
+         * 获取url对应的encoding值
+         * @param url 文件路径
+         * @param type 文件类型
+         * @return
+         */
+        static getUrlEncode(url: string, type: string): string;
+        /**
+         * 下载文件
+         * @param fileUrl 文件地址(全路径)
+         * @param fileType 文件类型(image、text、json、xml、arraybuffer、sound、atlas、font)
+         * @param callBack 文件加载回调,回调内容[errorCode码(0成功,1失败,2加载进度)
+         * @param encoding 文件编码默认utf8,非图片文件加载需要设置相应的编码,二进制编码为空字符串
+         */
+        static downLoadFile(fileUrl: string, fileType?: string, callBack?: Handler, encoding?: string): void;
+        /**
+         * 从本地删除文件
+         * @param fileUrl 文件地址(全路径)
+         * @param callBack 回调处理,在存储图片时用到
+         */
+        static remove(fileUrl: string, callBack?: Handler): void;
+        /**
+         * 清空缓存空间文件内容
+         */
+        static removeAll(): void;
+        /**
+         * 判断是否是4M包文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static hasNativeFile(fileUrl: string): boolean;
+        /**
+         * 判断缓存里是否存在文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static getFileInfo(fileUrl: string): any;
+        /**
+         * 获取缓存文件列表
+         * @return
+         */
+        static getFileList(): any;
+        static exitMiniProgram(): void;
+        static pixelRatio(): number;
+        static createElement(type: string): any;
+        static createShaderCondition(conditionScript: string): Function;
+        /**
+         * 传递图集url地址到
+         * @param url 为绝对地址
+         */
+        static sendAtlasToOpenDataContext(url: string): void;
+        /**
+         * 发送单张图片到开放数据域
+         * @param url
+         */
+        static sendSinglePicToOpenDataContext(url: string): void;
+        /**
+         * 传递json配置数据到开放数据域
+         * @param url 为绝对地址
+         */
+        static sendJsonDataToDataContext(url: string): void;
+    }
+}
+declare module laya.bd.mini {
+    import Handler = laya.utils.Handler;
+    class BMiniAdapter {
+        static EnvConfig: any;
+        /**全局window对象**/
+        static window: any;
+        static systemInfo: any;
+        static isZiYu: boolean;
+        static isPosMsgYu: boolean;
+        /**是否自动缓存下载的图片跟声音文件,默认为true**/
+        static autoCacheFile: boolean;
+        /**50M缓存容量满时每次清理容量值,默认每次清理5M**/
+        static minClearSize: number;
+        /**本地资源列表**/
+        static nativefiles: Array<any>;
+        /**本地分包资源表**/
+        static subNativeFiles: any;
+        /**本地分包文件目录数组**/
+        static subNativeheads: Array<any>;
+        /**本地分包文件目录映射表**/
+        static subMaps: Array<any>;
+        static AutoCacheDownFile: boolean;
+        static getJson(data: string): any;
+        /**激活微信小游戏适配器*/
+        static enable(): void;
+        /**
+         * 初始化回调
+         * @param isPosMsg 是否需要在主域中自动将加载的文本数据自动传递到子域,默认 false
+         * @param isSon 是否是子域,默认为false
+         */
+        static init(isPosMsg?: boolean, isSon?: boolean): void;
+        /**
+         * 获取url对应的encoding值
+         * @param url 文件路径
+         * @param type 文件类型
+         * @return
+         */
+        static getUrlEncode(url: string, type: string): string;
+        /**
+         * 下载文件
+         * @param fileUrl 文件地址(全路径)
+         * @param fileType 文件类型(image、text、json、xml、arraybuffer、sound、atlas、font)
+         * @param callBack 文件加载回调,回调内容[errorCode码(0成功,1失败,2加载进度)
+         * @param encoding 文件编码默认utf8,非图片文件加载需要设置相应的编码,二进制编码为空字符串
+         */
+        static downLoadFile(fileUrl: string, fileType?: string, callBack?: Handler, encoding?: string): void;
+        /**
+         * 从本地删除文件
+         * @param fileUrl 文件地址(全路径)
+         * @param callBack 回调处理,在存储图片时用到
+         */
+        static remove(fileUrl: string, callBack?: Handler): void;
+        /**
+         * 清空缓存空间文件内容
+         */
+        static removeAll(): void;
+        /**
+         * 判断是否是4M包文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static hasNativeFile(fileUrl: string): boolean;
+        /**
+         * 判断缓存里是否存在文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static getFileInfo(fileUrl: string): any;
+        /**
+         * 获取缓存文件列表
+         * @return
+         */
+        static getFileList(): any;
+        static exitMiniProgram(): void;
+        static pixelRatio(): number;
+        static createElement(type: string): any;
+        static createShaderCondition(conditionScript: string): Function;
+        /**
+         * 传递图集url地址到
+         * @param url 为绝对地址
+         */
+        static sendAtlasToOpenDataContext(url: string): void;
+        /**
+         * 发送单张图片到开放数据域
+         * @param url
+         */
+        static sendSinglePicToOpenDataContext(url: string): void;
+        /**
+         * 传递json配置数据到开放数据域
+         * @param url 为绝对地址
+         */
+        static sendJsonDataToDataContext(url: string): void;
+    }
+}
+declare module laya.mi.mini {
+    import Handler = laya.utils.Handler;
+    class KGMiniAdapter {
+        static EnvConfig: any;
+        /**全局window对象**/
+        static window: any;
+        static systemInfo: any;
+        static isZiYu: boolean;
+        static isPosMsgYu: boolean;
+        /**是否自动缓存下载的图片跟声音文件,默认为true**/
+        static autoCacheFile: boolean;
+        /**50M缓存容量满时每次清理容量值,默认每次清理5M**/
+        static minClearSize: number;
+        /**本地资源列表**/
+        static nativefiles: Array<any>;
+        /**本地分包资源表**/
+        static subNativeFiles: any;
+        /**本地分包文件目录数组**/
+        static subNativeheads: Array<any>;
+        /**本地分包文件目录映射表**/
+        static subMaps: Array<any>;
+        static AutoCacheDownFile: boolean;
+        static getJson(data: string): any;
+        /**激活微信小游戏适配器*/
+        static enable(): void;
+        /**
+         * 初始化回调
+         * @param isPosMsg 是否需要在主域中自动将加载的文本数据自动传递到子域,默认 false
+         * @param isSon 是否是子域,默认为false
+         */
+        static init(isPosMsg?: boolean, isSon?: boolean): void;
+        /**
+         * 获取url对应的encoding值
+         * @param url 文件路径
+         * @param type 文件类型
+         * @return
+         */
+        static getUrlEncode(url: string, type: string): string;
+        /**
+         * 下载文件
+         * @param fileUrl 文件地址(全路径)
+         * @param fileType 文件类型(image、text、json、xml、arraybuffer、sound、atlas、font)
+         * @param callBack 文件加载回调,回调内容[errorCode码(0成功,1失败,2加载进度)
+         * @param encoding 文件编码默认utf8,非图片文件加载需要设置相应的编码,二进制编码为空字符串
+         */
+        static downLoadFile(fileUrl: string, fileType?: string, callBack?: Handler, encoding?: string): void;
+        /**
+         * 从本地删除文件
+         * @param fileUrl 文件地址(全路径)
+         * @param callBack 回调处理,在存储图片时用到
+         */
+        static remove(fileUrl: string, callBack?: Handler): void;
+        /**
+         * 清空缓存空间文件内容
+         */
+        static removeAll(): void;
+        /**
+         * 判断是否是4M包文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static hasNativeFile(fileUrl: string): boolean;
+        /**
+         * 判断缓存里是否存在文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static getFileInfo(fileUrl: string): any;
+        /**
+         * 获取缓存文件列表
+         * @return
+         */
+        static getFileList(): any;
+        static exitMiniProgram(): void;
+        static pixelRatio(): number;
+        static createElement(type: string): any;
+        static createShaderCondition(conditionScript: string): Function;
+        /**
+         * 传递图集url地址到
+         * @param url 为绝对地址
+         */
+        static sendAtlasToOpenDataContext(url: string): void;
+        /**
+         * 发送单张图片到开放数据域
+         * @param url
+         */
+        static sendSinglePicToOpenDataContext(url: string): void;
+        /**
+         * 传递json配置数据到开放数据域
+         * @param url 为绝对地址
+         */
+        static sendJsonDataToDataContext(url: string): void;
+    }
+}
+declare module laya.qg.mini {
+    import Handler = laya.utils.Handler;
+    class QGMiniAdapter {
+        static EnvConfig: any;
+        /**全局window对象**/
+        static window: any;
+        static systemInfo: any;
+        static isZiYu: boolean;
+        static isPosMsgYu: boolean;
+        /**是否自动缓存下载的图片跟声音文件,默认为true**/
+        static autoCacheFile: boolean;
+        /**50M缓存容量满时每次清理容量值,默认每次清理5M**/
+        static minClearSize: number;
+        /**本地资源列表**/
+        static nativefiles: Array<any>;
+        /**本地分包资源表**/
+        static subNativeFiles: any;
+        /**本地分包文件目录数组**/
+        static subNativeheads: Array<any>;
+        /**本地分包文件目录映射表**/
+        static subMaps: Array<any>;
+        static AutoCacheDownFile: boolean;
+        static getJson(data: string): any;
+        /**激活微信小游戏适配器*/
+        static enable(): void;
+        /**
+         * 初始化回调
+         * @param isPosMsg 是否需要在主域中自动将加载的文本数据自动传递到子域,默认 false
+         * @param isSon 是否是子域,默认为false
+         */
+        static init(isPosMsg?: boolean, isSon?: boolean): void;
+        /**
+         * 获取url对应的encoding值
+         * @param url 文件路径
+         * @param type 文件类型
+         * @return
+         */
+        static getUrlEncode(url: string, type: string): string;
+        /**
+         * 下载文件
+         * @param fileUrl 文件地址(全路径)
+         * @param fileType 文件类型(image、text、json、xml、arraybuffer、sound、atlas、font)
+         * @param callBack 文件加载回调,回调内容[errorCode码(0成功,1失败,2加载进度)
+         * @param encoding 文件编码默认utf8,非图片文件加载需要设置相应的编码,二进制编码为空字符串
+         */
+        static downLoadFile(fileUrl: string, fileType?: string, callBack?: Handler, encoding?: string): void;
+        /**
+         * 从本地删除文件
+         * @param fileUrl 文件地址(全路径)
+         * @param callBack 回调处理,在存储图片时用到
+         */
+        static remove(fileUrl: string, callBack?: Handler): void;
+        /**
+         * 清空缓存空间文件内容
+         */
+        static removeAll(): void;
+        /**
+         * 判断是否是4M包文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static hasNativeFile(fileUrl: string): boolean;
+        /**
+         * 判断缓存里是否存在文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static getFileInfo(fileUrl: string): any;
+        /**
+         * 获取缓存文件列表
+         * @return
+         */
+        static getFileList(): any;
+        static exitMiniProgram(): void;
+        static pixelRatio(): number;
+        static createElement(type: string): any;
+        static createShaderCondition(conditionScript: string): Function;
+        /**
+         * 传递图集url地址到
+         * @param url 为绝对地址
+         */
+        static sendAtlasToOpenDataContext(url: string): void;
+        /**
+         * 发送单张图片到开放数据域
+         * @param url
+         */
+        static sendSinglePicToOpenDataContext(url: string): void;
+        /**
+         * 传递json配置数据到开放数据域
+         * @param url 为绝对地址
+         */
+        static sendJsonDataToDataContext(url: string): void;
+    }
+}
+
+declare module laya.vv.mini {
+    import Handler = laya.utils.Handler;
+    class VVMiniAdapter {
+        static EnvConfig: any;
+        /**全局window对象**/
+        static window: any;
+        static systemInfo: any;
+        static isZiYu: boolean;
+        static isPosMsgYu: boolean;
+        /**是否自动缓存下载的图片跟声音文件,默认为true**/
+        static autoCacheFile: boolean;
+        /**50M缓存容量满时每次清理容量值,默认每次清理5M**/
+        static minClearSize: number;
+        /**本地资源列表**/
+        static nativefiles: Array<any>;
+        /**本地分包资源表**/
+        static subNativeFiles: any;
+        /**本地分包文件目录数组**/
+        static subNativeheads: Array<any>;
+        /**本地分包文件目录映射表**/
+        static subMaps: Array<any>;
+        static AutoCacheDownFile: boolean;
+        static getJson(data: string): any;
+        /**激活微信小游戏适配器*/
+        static enable(): void;
+        /**
+         * 初始化回调
+         * @param isPosMsg 是否需要在主域中自动将加载的文本数据自动传递到子域,默认 false
+         * @param isSon 是否是子域,默认为false
+         */
+        static init(isPosMsg?: boolean, isSon?: boolean): void;
+        /**
+         * 获取url对应的encoding值
+         * @param url 文件路径
+         * @param type 文件类型
+         * @return
+         */
+        static getUrlEncode(url: string, type: string): string;
+        /**
+         * 下载文件
+         * @param fileUrl 文件地址(全路径)
+         * @param fileType 文件类型(image、text、json、xml、arraybuffer、sound、atlas、font)
+         * @param callBack 文件加载回调,回调内容[errorCode码(0成功,1失败,2加载进度)
+         * @param encoding 文件编码默认utf8,非图片文件加载需要设置相应的编码,二进制编码为空字符串
+         */
+        static downLoadFile(fileUrl: string, fileType?: string, callBack?: Handler, encoding?: string): void;
+        /**
+         * 从本地删除文件
+         * @param fileUrl 文件地址(全路径)
+         * @param callBack 回调处理,在存储图片时用到
+         */
+        static remove(fileUrl: string, callBack?: Handler): void;
+        /**
+         * 清空缓存空间文件内容
+         */
+        static removeAll(): void;
+        /**
+         * 判断是否是4M包文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static hasNativeFile(fileUrl: string): boolean;
+        /**
+         * 判断缓存里是否存在文件
+         * @param fileUrl 文件地址(全路径)
+         * @return
+         */
+        static getFileInfo(fileUrl: string): any;
+        /**
+         * 获取缓存文件列表
+         * @return
+         */
+        static getFileList(): any;
+        static exitMiniProgram(): void;
+        static pixelRatio(): number;
+        static createElement(type: string): any;
+        static createShaderCondition(conditionScript: string): Function;
+        /**
+         * 传递图集url地址到
+         * @param url 为绝对地址
+         */
+        static sendAtlasToOpenDataContext(url: string): void;
+        /**
+         * 发送单张图片到开放数据域
+         * @param url
+         */
+        static sendSinglePicToOpenDataContext(url: string): void;
+        /**
+         * 传递json配置数据到开放数据域
+         * @param url 为绝对地址
+         */
+        static sendJsonDataToDataContext(url: string): void;
+    }
+}
+
+declare module Laya {
+    class MiniAdpter extends laya.wx.mini.MiniAdpter {
+    }
+    class BMiniAdapter extends laya.bd.mini.BMiniAdapter {
+    }
+    class KGMiniAdapter extends laya.mi.mini.KGMiniAdapter {
+    }
+    class QGMiniAdapter extends laya.qg.mini.QGMiniAdapter {
+    }
+    class VVMiniAdapter extends laya.vv.mini.VVMiniAdapter {
+    }
+}

ファイルの差分が大きいため隠しています
+ 6118 - 0
libs/union.d.ts


ファイルの差分が大きいため隠しています
+ 5639 - 0
libs/wx.d.ts


+ 3 - 0
src/Game/AssetManager.ts

@@ -0,0 +1,3 @@
+export class AssetManager{
+    
+}

+ 14 - 0
src/Game/Ball.ts

@@ -0,0 +1,14 @@
+export class Ball extends Laya.Script{
+    constructor(){
+        super();
+    }
+    _ball:Laya.Image;
+    onAwake(){
+
+    }
+    onEnable(){
+        this._ball = this.owner as Laya.Image;
+    }
+    
+    
+}

+ 38 - 0
src/Game/BallControl.ts

@@ -0,0 +1,38 @@
+import Dictionary from "../Tool/Dictionary";
+import { Ball } from "./Ball";
+
+export class BallControl{
+    constructor(){
+        this._dictionary = new Dictionary();
+    }
+    _dictionary:Dictionary;
+
+    CreatBall(_name:string):Laya.Image{
+        let ball = this.GetBallforPool("ball"+_name);
+        return ball;
+    }
+    private GetBallforPool(_name) {
+        if (this._dictionary.has(_name)) {
+            if (this._dictionary.get(_name).length > 0) {
+                var result = this._dictionary.get(_name).shift();
+                return result;
+            } else {
+                var tips = Laya.loader.getRes("Prefab_Ball/" + _name + ".json");
+                var pre = new Laya.Prefab();
+                pre.json = tips;
+                var item = pre.create() as Laya.Image;
+                item.name = _name;
+                item.addComponent(Ball);
+                return item;
+            }
+        } else {
+            var tips = Laya.loader.getRes("Prefab_Ball/" + _name + ".json");
+            var pre = new Laya.Prefab();
+            pre.json = tips;
+            var item = pre.create() as Laya.Image;
+            item.name = _name;
+            item.addComponent(Ball);
+            return item;
+        }
+    }
+}

+ 5 - 0
src/Game/LoadAsset.ts

@@ -0,0 +1,5 @@
+export class LoadAsset{
+    constructor(){
+        
+    }
+}

+ 25 - 0
src/GameConfig.ts

@@ -0,0 +1,25 @@
+/**This class is automatically generated by LayaAirIDE, please do not make any modifications. */
+
+/*
+* 游戏初始化配置;
+*/
+export default class GameConfig{
+    static width:number=640;
+    static height:number=1136;
+    static scaleMode:string="fixedwidth";
+    static screenMode:string="none";
+    static alignV:string="top";
+    static alignH:string="left";
+    static startScene:any="";
+    static sceneRoot:string="";
+    static debug:boolean=false;
+    static stat:boolean=false;
+    static physicsDebug:boolean=false;
+    static exportSceneToJson:boolean=true;
+    constructor(){}
+    static init(){
+        var reg: Function = Laya.ClassUtils.regClass;
+
+    }
+}
+GameConfig.init();

+ 37 - 0
src/Main.ts

@@ -0,0 +1,37 @@
+import GameConfig from "./GameConfig";
+class Main {
+	constructor() {
+		//根据IDE设置初始化引擎		
+		if (window["Laya3D"]) Laya3D.init(GameConfig.width, GameConfig.height);
+		else Laya.init(GameConfig.width, GameConfig.height, Laya["WebGL"]);
+		Laya["Physics"] && Laya["Physics"].enable();
+		Laya["DebugPanel"] && Laya["DebugPanel"].enable();
+		Laya.stage.scaleMode = GameConfig.scaleMode;
+		Laya.stage.screenMode = GameConfig.screenMode;
+		Laya.stage.alignV = GameConfig.alignV;
+		Laya.stage.alignH = GameConfig.alignH;
+		//兼容微信不支持加载scene后缀场景
+		Laya.URL.exportSceneToJson = GameConfig.exportSceneToJson;
+
+		//打开调试面板(通过IDE设置调试模式,或者url地址增加debug=true参数,均可打开调试面板)
+		if (GameConfig.debug || Laya.Utils.getQueryString("debug") == "true") Laya.enableDebugPanel();
+		if (GameConfig.physicsDebug && Laya["PhysicsDebugDraw"]) Laya["PhysicsDebugDraw"].enable();
+		if (GameConfig.stat) Laya.Stat.show();
+		Laya.alertGlobalError = true;
+
+		//激活资源版本控制,version.json由IDE发布功能自动生成,如果没有也不影响后续流程
+		Laya.ResourceVersion.enable("version.json", Laya.Handler.create(this, this.onVersionLoaded), Laya.ResourceVersion.FILENAME_VERSION);
+	}
+
+	onVersionLoaded(): void {
+		//激活大小图映射,加载小图的时候,如果发现小图在大图合集里面,则优先加载大图合集,而不是小图
+		Laya.AtlasInfoManager.enable("fileconfig.json", Laya.Handler.create(this, this.onConfigLoaded));
+	}
+
+	onConfigLoaded(): void {
+		//加载IDE指定的场景
+		GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
+	}
+}
+//激活启动类
+new Main();

+ 56 - 0
src/Tool/Dictionary.ts

@@ -0,0 +1,56 @@
+
+export default class Dictionary {
+    private _length: number;
+
+    private _container: any;
+
+    constructor() {
+        this._container = {};
+        this._length = 0;
+    }
+
+    public get container(): any {
+        return this._container;
+    }
+
+    //获取字典长度    
+    public get size(): number {
+        return this._length;
+    }
+
+    //添加
+    public set(key: any, value: any): void {
+        if (!this._container.hasOwnProperty(key))  {
+            this._length++;
+        }
+        this._container[key] = value;
+    }
+
+    //删除     
+    public delete(key: any): void {
+        if (this._container.hasOwnProperty(key))  {
+            delete this._container[key];
+            this._length--;
+        }
+    }
+
+    //查找   
+    public has(key: any): boolean {
+        return this._container.hasOwnProperty(key) ? true : false;
+    }
+
+    //获取 
+    public get(key: any): any {
+        if (this._container.hasOwnProperty(key))  {
+            return this._container[key];
+        } else  {
+            return undefined
+        }
+    }
+
+    //清空    
+    public clear() {
+        this._container = {};
+        this._length = 0;
+    }
+}

+ 64 - 0
src/Tool/GamePool.ts

@@ -0,0 +1,64 @@
+export class GamePool{
+    private static ins:GamePool;
+    constructor(){
+        GamePool.ins = this;
+    }
+    
+    //最大存储数量
+    private maxAcount:number = 30;
+
+    public static get Instance():GamePool{
+        if(GamePool.ins){
+            return GamePool.ins
+        }
+        else{
+            return new GamePool();
+        }
+    }
+    //模型库
+    private modelpool : {[Key:string]:Array<Laya.Image> } = {};
+    //获取模型
+    public GetModel(title:string):Laya.Image{
+        let poolname = title ;
+        if(this.modelpool[poolname]!=null && this.modelpool[poolname]!=undefined){
+            if(this.modelpool[poolname].length >0){
+                let model1 = this.modelpool[poolname].shift();
+                if(!model1.active){
+                    model1.active = true;  
+                }
+                return model1;
+            }
+            else{
+                let model = new Laya.Image();
+                model.name=title;
+                return model;
+            }
+        }
+        else{
+            let model = new Laya.Image();
+            model.name=title;
+            return model;
+        }
+    }
+    //回收模型
+    public RecoverModel(_image:Laya.Image,title = "",modelstate = false){
+        if(_image.destroyed){
+            return;
+        }
+        if(!modelstate && _image.active == false){
+            return;
+        }
+       let poolname = title ; 
+        if(this.modelpool[poolname] != null && this.modelpool[poolname] != undefined){
+           let modelnum = this.modelpool[poolname];
+           this.modelpool[poolname].push(_image);
+        }
+        else{
+            let modelnum = [];
+            modelnum.push(_image);
+            this.modelpool[poolname] = modelnum;
+        }
+        _image.removeSelf();
+        _image.active = false;
+    }
+}

+ 251 - 0
src/Tool/GameTool.ts

@@ -0,0 +1,251 @@
+
+export class faafssfafsa
+{
+    constructor(_message:string,_pos:Laya.Vector2,_size:Laya.Vector2,_fontSize:number,_color:string = null)
+    {
+        this.size = new Laya.Vector2(_size.x,_size.y);
+        this.fontSize = _fontSize;
+        this.color = _color;
+        this.message = _message;
+        this.pos = _pos;
+    }
+    size:Laya.Vector2;
+    fontSize = 30;
+    color:string;
+    message = "";
+    pos:Laya.Vector2;
+}
+export  class GameTool  {
+    private static ins:GameTool;
+    constructor() {
+        GameTool.ins = this; 
+     }
+    /**单例*/
+    public static get Instance():GameTool{
+        if(GameTool.ins){
+            return GameTool.ins;
+        }
+        else{
+            return new GameTool();
+        }
+    }
+    
+    /**插值方法*/
+    public  lerp(form:number, to:number, t:number){
+        if (t <= 0) {
+            return form;
+        }else if (t >= 1) {
+            return to;
+        }
+        var a = t * to + (1 - t) * form
+        return a;
+     }
+    /**设置碰撞器*/
+    SetCollider(setNode: Laya.Node, CollisionGroup: number) {
+        var numchild = setNode.numChildren;
+        for (var i = 0; i < setNode.numChildren; i++) {
+            var numchild2 = setNode.getChildAt(i).numChildren;
+            if (numchild2 > 1) {
+                this.SetCollider(setNode.getChildAt(i), CollisionGroup);
+            }
+            var physicsCollider = setNode.getChildAt(i).getComponent(Laya.PhysicsCollider) as Laya.PhysicsCollider;
+            if (physicsCollider) {
+                physicsCollider.collisionGroup = CollisionGroup;
+            }
+        }
+    }
+    //随机一个浮点数
+    public static RandomNumber(from:number,to:number):number
+    {
+        if(from >= to)
+        {
+            return 0;
+        }
+        var size = to - from;
+        var curNumber = Math.random()*size + from;
+        return curNumber;
+    }
+    //随机一个int值
+    public static RandomANumber(from:number,to:number):number
+    {
+        if(from >= to)
+        {
+            return 0;
+        }
+        var size = to - from;
+        var curNumber = Math.random()*size + from;
+        return Math.floor(curNumber);
+    }
+
+    //签到领取金币Tween动画
+    public static GetMoney(_num:number,_pos:Laya.Vector2 = null,_completeHandle:Laya.Handler = null)
+    {
+        if(_num == 0)return;
+        var fafaafsfa = new Laya.Box;
+        fafaafsfa.width = 400;
+        fafaafsfa.height = 100;
+        fafaafsfa.pivotX = fafaafsfa.width/2;
+        fafaafsfa.pivotY = fafaafsfa.height/2;
+        if(_pos == null)
+        {
+            _pos = new Laya.Vector2(Laya.stage.width/2,Laya.stage.height/2);
+        }
+        fafaafsfa.pos(_pos.x,_pos.y);
+
+        var aafafaffa = new Laya.Image;
+        aafafaffa.skin = "game/qiandao_1_7.png";
+        aafafaffa.width = 60;
+        aafafaffa.height = 60;
+        aafafaffa.left = 50;
+        aafafaffa.y = 10;
+        fafaafsfa.addChild(aafafaffa);
+
+        var faasfafsafs = new Laya.Text;
+        faasfafsafs.width = 300;
+        faasfafsafs.height = 50;
+        
+        faasfafsafs.align = "center";
+        faasfafsafs.valign = "middle";
+        faasfafsafs.font = "Microsoft YaHei";
+        faasfafsafs.fontSize = 40;
+        faasfafsafs.color = "#FFFFFF";
+        faasfafsafs.bold = true;
+        faasfafsafs.font = "Microsoft YaHei";
+        faasfafsafs.text = "金币 +" + _num;
+        faasfafsafs.x = 60;
+        faasfafsafs.y = 10;
+        fafaafsfa.addChild(faasfafsafs);
+        
+        
+        Laya.stage.addChild(fafaafsfa);
+
+        var faasfsaf = Laya.Tween.to(fafaafsfa,{y:fafaafsfa.y - 200},1500,Laya.Ease.expoInOut,Laya.Handler.create(this,()=>
+        {
+            faasfsaf.clear();
+            fafaafsfa.destroy();
+            if(_completeHandle)
+            {
+                _completeHandle.run();
+            }
+        }),100);
+
+    }
+    //文字Tween动画
+    public static TweenText(faafssfafsa:faafssfafsa,_hight:number,_completeHandle:Laya.Handler = null,hide = true,_duration:number = 500):Laya.Text
+    {
+        var afasafsafsfa = new Laya.Text();
+        
+        afasafsafsfa.width = faafssfafsa.size.x;
+        afasafsafsfa.height = faafssfafsa.size.y;
+        afasafsafsfa.align = "center";
+        afasafsafsfa.valign = "middle";
+        afasafsafsfa.font = "Microsoft YaHei";
+        afasafsafsfa.fontSize = faafssfafsa.fontSize;
+        afasafsafsfa.pivotX = afasafsafsfa.width/2;
+        afasafsafsfa.pivotY =  afasafsafsfa.height/2;
+        afasafsafsfa.color = "#5ad122";
+        afasafsafsfa.bold = true;
+        afasafsafsfa.stroke = 5;
+        afasafsafsfa.strokeColor = "#ffffff";
+        if(faafssfafsa.color)
+        {
+            faafssfafsa.color = faafssfafsa.color;
+        }
+        afasafsafsfa.text = faafssfafsa.message;
+        afasafsafsfa.zOrder = 1;
+        Laya.stage.addChildAt(afasafsafsfa,Laya.stage.numChildren - 1);
+        afasafsafsfa.pos(faafssfafsa.pos.x,faafssfafsa.pos.y);
+        var tween = Laya.Tween.to(afasafsafsfa,{y:afasafsafsfa.y - _hight,update:new Laya.Handler(this,function()
+            {
+
+            })},_duration,Laya.Ease.expoInOut,Laya.Handler.create(this,function()
+        {
+            tween.clear();
+            if(hide)
+            {
+                afasafsafsfa.destroy();
+            }
+            if(_completeHandle)
+            {
+                _completeHandle.run();
+            }
+        }));
+        if(hide)
+        {
+            Laya.Tween.to(afasafsafsfa,{alpha:0.4},500);
+        }
+        return afasafsafsfa;
+    }
+
+        //文字Tween动画
+        public static StationTweenText(faafssfafsa:faafssfafsa,_hight:number,_completeHandle:Laya.Handler = null,hide = true,_duration:number = 500):Laya.Text
+        {
+            var afasafsafsfa = new Laya.Text();
+            
+            afasafsafsfa.width = faafssfafsa.size.x;
+            afasafsafsfa.height = faafssfafsa.size.y;
+            afasafsafsfa.align = "center";
+            afasafsafsfa.valign = "middle";
+            afasafsafsfa.font = "Microsoft YaHei";
+            afasafsafsfa.fontSize = 50;
+            afasafsafsfa.pivotX = afasafsafsfa.width/2;
+            afasafsafsfa.pivotY =  afasafsafsfa.height/2;
+            afasafsafsfa.color = "#5ad122";
+            afasafsafsfa.bold = true;
+            afasafsafsfa.stroke = 5;
+            afasafsafsfa.strokeColor = "#ffffff";
+            if(faafssfafsa.color)
+            {
+                faafssfafsa.color = faafssfafsa.color;
+            }
+            afasafsafsfa.text = faafssfafsa.message;
+            afasafsafsfa.zOrder = 1;
+            Laya.stage.addChildAt(afasafsafsfa,Laya.stage.numChildren - 1);
+            afasafsafsfa.pos(faafssfafsa.pos.x,faafssfafsa.pos.y);
+            var tween = Laya.Tween.to(afasafsafsfa,{y:afasafsafsfa.y - _hight,update:new Laya.Handler(this,function()
+                {
+    
+                })},_duration,Laya.Ease.expoInOut,Laya.Handler.create(this,function()
+            {
+                tween.clear();
+                if(hide)
+                {
+                    afasafsafsfa.destroy();
+                }
+                if(_completeHandle)
+                {
+                    _completeHandle.run();
+                }
+            }));
+            if(hide)
+            {
+                Laya.Tween.to(afasafsafsfa,{alpha:0.4},10000);
+            }
+            return afasafsafsfa;
+        }
+
+    static tweenMove(transform: Laya.Transform3D, targPos: Laya.Vector3, delay: number, ease: Function, complete: Laya.Handler): Laya.Tween {
+        let curPos = transform.position.clone();
+        return Laya.Tween.to(curPos, {
+            x: targPos.x,
+            y: targPos.y,
+            z: targPos.z,
+            update: new Laya.Handler(this, () => {
+                transform.position = curPos.clone();
+            })
+        }, delay, ease, complete);
+    }
+
+    static tweenRotate(transform: Laya.Transform3D, targEuler: Laya.Vector3, delay: number, ease: Function, complete: Laya.Handler): Laya.Tween {
+        let curEuler = transform.rotationEuler.clone();
+        return Laya.Tween.to(curEuler, {
+            x: targEuler.x,
+            y: targEuler.y,
+            z: targEuler.z,
+            update: new Laya.Handler(this, () => {
+                transform.rotationEuler = curEuler.clone();
+            })
+        }, delay, ease, complete);
+    }
+    
+}

+ 11 - 0
tsconfig.json

@@ -0,0 +1,11 @@
+{
+  "compilerOptions": {
+    "module": "es6",
+    "target": "es6",
+    "noEmitHelpers": true,
+    "sourceMap": false
+  },
+  "exclude": [
+    "node_modules"
+  ]
+}