初始提交:三玩法 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
@@ -0,0 +1,22 @@
import type { Draw } from '../src/view';
export function paint(ctx: CanvasRenderingContext2D, commands: Draw[]): void {
for (const d of commands) {
ctx.save(); ctx.globalAlpha = d.alpha ?? 1;
ctx.fillStyle = d.fill || 'transparent'; ctx.strokeStyle = d.stroke || 'transparent';
ctx.lineWidth = d.width || 1; ctx.lineCap = 'round'; ctx.lineJoin = 'round';
ctx.beginPath();
if (d.type === 'circle') ctx.arc(d.x, d.y, Math.max(0, d.r), 0, Math.PI * 2);
else if (d.type === 'ellipse') ctx.ellipse(d.x, d.y, d.rx, d.ry, 0, 0, Math.PI * 2);
else if (d.type === 'path') {
if (d.dash) ctx.setLineDash(d.dash);
d.points.forEach((p, i) => i ? ctx.lineTo(p.x, p.y) : ctx.moveTo(p.x, p.y));
if (d.close) ctx.closePath();
} else {
ctx.font = `${d.weight || 600} ${d.size}px "Avenir Next", "Nunito", "PingFang SC", sans-serif`;
ctx.textAlign = d.align || 'center'; ctx.textBaseline = 'middle';
if (d.stroke) ctx.strokeText(d.text, d.x, d.y);
ctx.fillText(d.text, d.x, d.y); ctx.restore(); continue;
}
if (d.fill) ctx.fill(); if (d.stroke) ctx.stroke(); ctx.restore();
}
}