初始提交:三玩法 Web 原型与设计文档

- 玩法一 数字一笔:规则库、求解器、26 关、竖屏触摸 Web 原型、测试
- 玩法二 连连气球:连消畅玩版核心、Web 原型、Cocos 球槽组件与导出脚本
- 玩法三 六边一笔:规则库、求解器、10 关 + 转墙实验包、Web 原型、测试
- 产品文档、UI 设计规范、各玩法 GDD / HANDOFF
- 文档移除全部外部参考作引用;删除玩法二 v0 旧稿
This commit is contained in:
cabinw
2026-09-16 14:30:59 +08:00
commit 8026e4628d
169 changed files with 22162 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
import * as esbuild from 'esbuild';
import { networkInterfaces } from 'node:os';
import { mkdir, copyFile } from 'node:fs/promises';
const args = process.argv.slice(2);
const serve = args.includes('--serve');
const index = args.indexOf('--port');
const port = index >= 0 ? Number(args[index + 1]) : Number(process.env.PORT || 8002);
const ctx = await esbuild.context({
entryPoints: ['web/main.ts'], bundle: true, format: 'iife', target: 'es2020',
outfile: serve ? 'web/dist/app.js' : 'release/dist/app.js', minify: !serve, sourcemap: serve, logLevel: 'info',
define: { __DEV__: JSON.stringify(serve) },
});
if (serve) {
await ctx.watch();
const result = await ctx.serve({ host: '0.0.0.0', port, servedir: 'web' });
console.log(`\n连连气球 http://localhost:${result.port}`);
for (const item of Object.values(networkInterfaces()).flat()) {
if (item?.family === 'IPv4' && !item.internal) console.log(`手机同一 Wi-Fi: http://${item.address}:${result.port}`);
}
} else {
await mkdir('release', { recursive: true });
for (const file of ['index.html', 'style.css']) await copyFile(`web/${file}`, `release/${file}`);
await ctx.rebuild();
await ctx.dispose();
console.log('离线 / 静态发布目录:release/');
}
@@ -0,0 +1,22 @@
import { access, readdir, writeFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import { spawnSync } from 'node:child_process';
let declarations = process.argv[2] || process.env.COCOS_TYPES;
if (!declarations) {
const root = '/Applications/Cocos/Creator';
try {
for (const version of (await readdir(root)).sort((a, b) => b.localeCompare(a, undefined, { numeric: true }))) {
const candidate = `${root}/${version}/CocosCreator.app/Contents/Resources/resources/3d/engine/bin/.declarations/cc.d.ts`;
try { await access(candidate); declarations = candidate; break; } catch {}
}
} catch {}
}
if (!declarations) throw new Error('请用 COCOS_TYPES 或命令参数提供 Creator 的 cc.d.ts 路径。');
const target = resolve('cocos/export/02-connect-1234');
const config = resolve('cocos/export/tsconfig.check.json');
await writeFile(config, JSON.stringify({ compilerOptions: { target: 'ES2020', module: 'ESNext', moduleResolution: 'Bundler',
lib: ['ES2020', 'DOM'], strict: true, experimentalDecorators: true, useDefineForClassFields: false,
noEmit: true, skipLibCheck: true, types: [], baseUrl: '.', paths: { cc: [resolve(declarations)] } }, include: [target] }, null, 2));
console.log(`检查真实 Creator 类型:${declarations}`);
const result = spawnSync(process.execPath, ['node_modules/typescript/bin/tsc', '-p', config], { stdio: 'inherit' });
process.exit(result.status ?? 1);
@@ -0,0 +1,20 @@
import { mkdir, rm, readFile, writeFile, copyFile } from 'node:fs/promises';
import { resolve, join } from 'node:path';
const target = resolve(process.argv[2] || 'cocos/export/02-connect-1234');
// 默认目录是可再生构建产物,清掉 v1 遗留;自定义导出目录不删除用户文件。
if (!process.argv[2]) await rm(target, {recursive:true, force:true});
for (const dir of ['src', 'levels', 'adapters']) await mkdir(join(target, dir), { recursive: true });
const active = ['flow.ts', 'flow-rules.ts', 'cascade.ts', 'supply.ts', 'flow-animation.ts', 'record.ts', 'input.ts', 'rules.ts', 'types.ts', 'config.ts', 'physics.ts', 'random.ts', 'view.ts', 'storage.ts'];
for (const name of active) {
if (!name.endsWith('.ts')) continue;
let source = await readFile(join('src', name), 'utf8');
// Creator 不必依赖 bundler 的 JSON module 支持,导出时生成等价 TypeScript 数据模块。
source = source.replace("'../levels/spawn.json'", "'../levels/spawn-data'").replace("'../levels/campaign.json'", "'../levels/campaign-data'");
await writeFile(join(target, 'src', name), source);
}
for (const name of ['spawn']) {
const json = await readFile(`levels/${name}.json`, 'utf8');
await writeFile(join(target, 'levels', `${name}-data.ts`), `// 由 export-cocos.mjs 生成;在原始 levels/${name}.json 编辑。\nexport default ${json.trim()};\n`);
}
await copyFile('cocos/Connect1234Board.ts', join(target, 'adapters/Connect1234Board.ts'));
console.log(`Cocos 迁移包已导出:${target}`);