Complete Cocos Creator port with level bundles, themes, and tooling.

Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-16 15:30:58 +08:00
parent cba5105908
commit d393302388
6248 changed files with 17322729 additions and 11036 deletions

106
tools/package-optimize.js Normal file
View File

@@ -0,0 +1,106 @@
/**
* 打包优化关卡库压缩、settings 预加载策略、体积报告。
* 供 package-for-project.js / package-for-cdn.js 共用。
*/
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
function formatBytes(n) {
if (n >= 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)} MB`;
if (n >= 1024) return `${(n / 1024).toFixed(1)} KB`;
return `${n} B`;
}
function dirSize(root) {
if (!fs.existsSync(root)) return 0;
let total = 0;
for (const ent of fs.readdirSync(root, { withFileTypes: true })) {
const p = path.join(root, ent.name);
if (ent.isDirectory()) total += dirSize(p);
else total += fs.statSync(p).size;
}
return total;
}
function fileSize(p) {
return fs.existsSync(p) ? fs.statSync(p).size : 0;
}
/** 压缩关卡库 JSON去掉空白不改变语义 */
function minifyLevelsDatabase(srcPath, dstPath) {
const raw = fs.readFileSync(srcPath, 'utf8');
const data = JSON.parse(raw);
const compact = JSON.stringify(data);
fs.writeFileSync(dstPath, compact, 'utf8');
return { before: Buffer.byteLength(raw, 'utf8'), after: Buffer.byteLength(compact, 'utf8') };
}
/** 可选:生成 .br 供静态服务器直接返回 */
function brotliCompressFile(srcPath, dstPath, quality = 9) {
const input = fs.readFileSync(srcPath);
const out = zlib.brotliCompressSync(input, {
params: { [zlib.constants.BROTLI_PARAM_QUALITY]: quality },
});
fs.writeFileSync(dstPath, out);
return { raw: input.length, br: out.length };
}
/**
* 调整预加载 bundle默认只预加载 mainresources / level-prefabs 按需加载。
* @param {object} opts
* @param {boolean} [opts.preloadResources=false]
* @param {boolean} [opts.preloadLevelPrefabs=false]
*/
function patchPreloadSettings(settingsObj, opts = {}) {
const preloadResources = opts.preloadResources === true;
const preloadLevelPrefabs = opts.preloadLevelPrefabs === true;
const bundles = settingsObj.assets?.projectBundles || [];
const preload = [{ bundle: 'main' }];
if (preloadResources && bundles.includes('resources')) {
preload.push({ bundle: 'resources' });
}
if (preloadLevelPrefabs && bundles.includes('level-prefabs')) {
preload.push({ bundle: 'level-prefabs' });
}
settingsObj.assets = settingsObj.assets || {};
settingsObj.assets.preloadBundles = preload;
return settingsObj;
}
function printPackageReport(outDir, opts = {}) {
const lines = ['\n>>> 包体积报告:'];
const entries = [
['cocos-js', path.join(outDir, 'cocos-js')],
['src', path.join(outDir, 'src')],
['assets/main', path.join(outDir, 'assets', 'main')],
['assets/resources', path.join(outDir, 'assets', 'resources')],
['assets/level-prefabs', path.join(outDir, 'assets', 'level-prefabs')],
['assets/internal', path.join(outDir, 'assets', 'internal')],
['levels-database.json', path.join(outDir, 'levels-database.json')],
['levels-database.json.br', path.join(outDir, 'levels-database.json.br')],
['Build', path.join(outDir, 'Build')],
];
let total = 0;
for (const [label, p] of entries) {
if (!fs.existsSync(p)) continue;
const sz = fs.statSync(p).isDirectory() ? dirSize(p) : fileSize(p);
if (sz <= 0) continue;
total += sz;
lines.push(` ${label.padEnd(28)} ${formatBytes(sz)}`);
}
const grand = dirSize(outDir);
lines.push(` ${'合计(顶层目录)'.padEnd(28)} ${formatBytes(grand)}`);
if (opts.preloadNote) lines.push(` 预加载: ${opts.preloadNote}`);
console.log(lines.join('\n'));
}
module.exports = {
formatBytes,
dirSize,
fileSize,
minifyLevelsDatabase,
brotliCompressFile,
patchPreloadSettings,
printPackageReport,
};