345 lines
27 KiB
Markdown
345 lines
27 KiB
Markdown
# 数字一笔画 · 明亮教具室程序化美术实现方案
|
||
|
||
日期:2026-10-21|状态:技术方案,尚未接入运行时|首个落地版本:`wechat-campaign-200-r2`
|
||
|
||
以 **Canvas 2D 路径几何+参数化二维材质+状态驱动动效** 实现明亮教具室。背景、积木、桥接、图标、按钮和特效全部由程序生成,形成暖黄纸板、奶油教具垫、轻厚度彩色积木的视觉层次。
|
||
|
||
本方案承接[完整美术与 UI 设计报告](2026-10-21_美术设计-明亮教具室-report.md)及其[设计令牌](design/bright-classroom/tokens.json)。本次交付实现设计,不修改规则、正式渲染、关卡和发布包。
|
||
|
||
## 1. 制作原则与资源边界
|
||
|
||
### 1.1 “不用图片”的执行定义
|
||
|
||
| 内容 | 生产方式 | 交付形式 |
|
||
|---|---|---|
|
||
| 背景、舞台、积木、按钮 | 圆角路径、多边形、实色、有限渐变 | JavaScript 绘制模块 |
|
||
| 功能图标、类别、墙门、通道 | 归一化坐标、线段、圆弧、贝塞尔曲线 | 路径命令与参数 |
|
||
| 数字、中文 | 字体绘制;数字可选专用轮廓 | 字体文件或矢量路径数据 |
|
||
| 首页标题 | 第一版用字体叠绘;精修版用原创字形轮廓 | 文字排版或路径数据 |
|
||
| 动效、扫光、少量纸片 | 时间插值、裁切、几何粒子 | 动画代码 |
|
||
| 绘制缓存 | 运行时生成的离屏 Canvas | 临时内存,可随时重建 |
|
||
|
||
游戏不加载 PNG、JPG、WebP、预烘焙阴影图、图标贴图、粒子贴图或图片图集。参考图只用于美术比对,不进入运行包。不用 SVG 图片加载器绕过限制;如需要矢量形状,直接执行路径命令。
|
||
|
||
离屏缓存由代码生成,不属于外部图片美术资源;现有 `drawImage(boardCanvas, …)` 这种 Canvas 合成可以保留。字体是文字资源,音频沿用已有方案,二者与图片资源分别管理。
|
||
|
||
### 1.2 风格还原的着力点
|
||
|
||
优先还原“大色面、圆角、短底沿、左上亮边、干净数字、短促按压”。参考图中的颗粒、软糯高光和明显浮雕数字不作为生产目标,避免密集关变糊。二维分层足以建立所需触感,首版继续使用当前 Canvas 渲染链路。
|
||
|
||
首页可承载更多品牌厚度;正式对局缩小标题,让棋盘成为主物体。材质强弱按单位格节距决定,2×2 大块与普通块使用同一厚度、圆角基准和数字字号。
|
||
|
||
## 2. 当前工程与接入路线
|
||
|
||
### 2.1 已有能力和实际缺口
|
||
|
||
| 已核对来源 | 当前行为 | 对实施的影响 |
|
||
|---|---|---|
|
||
| `src/main.mjs` | Canvas 绘制导航、按钮、选关、规则面板;合成棋盘和提示 Canvas | UI 和棋盘必须一起升级 |
|
||
| `src/upstream/ui.mjs` | `localGeometry`、`paintCell`、`drawBridge`、`drawBarrier` 已程序绘制 | 可沿用几何来源,重做材质和信息布局 |
|
||
| `src/upstream/rules.mjs` | 提供 `units`、`outlineUnits`、共边、墙门状态和判定 | 逻辑结果由此消费,不在美术层重算规则 |
|
||
| `src/hints.mjs` | 独立透明层,擦除已走单位多边形,按中心点连线 | 应升级为新几何遮罩及语义避让 |
|
||
| `build.mjs` | 构建时变换上游 UI,注入微信宿主、分段提示和教学入口 | 皮肤接入需纳入受检查的构建变换 |
|
||
|
||
当前 `draw()` 同时负责几何、表现和按钮状态回写;不能整段替换而漏掉剩余块数、教学反馈、撤销禁用与下一关显隐。当前异形轮廓工具只追踪一个闭环,不能直接声称支持带内孔的单块。当前完成态亮紫、类别冲突整面染红,也需改成报告规定的状态合成。
|
||
|
||
### 2.2 建议的模块拆分
|
||
|
||
以下是拟新增模块,当前尚不存在;统一位于 `wechat-campaign-200-r2/src/bright-classroom/`。
|
||
|
||
| 模块 | 责任 | 不承担的工作 |
|
||
|---|---|---|
|
||
| `theme.mjs` | 消费原设计令牌、派生随 u 变化的材质参数 | 不另建一套手写颜色 |
|
||
| `geometry.mjs` | 多环轮廓、偏移、圆角、安全区、共边入口 | 不决定合法邻接 |
|
||
| `scene.mjs` | 把现有规则结果转换为块、边、标注、遮罩的表现数据 | 不调用求解器决定玩家行为 |
|
||
| `material.mjs` | 底沿、块面、边界、亮边和投影 | 不画数字或规则 |
|
||
| `board-renderer.mjs` | 组织棋盘各绘制通道 | 不写存档和播放声音 |
|
||
| `symbols.mjs` | 数字辅助框、奇偶、通道、类别、墙门 | 不以图形碰撞替代判定 |
|
||
| `icons.mjs`、`ui.mjs` | 统一图标与按钮、面板、标签 | 不显示未实现的设置能力 |
|
||
| `layout.mjs` | 舞台、UI、安全区、文字保留区和输入坐标变换 | 不改变关卡格点 |
|
||
| `motion.mjs` | 时间轴、按压、门切换、扫光、减少动态 | 不阻塞输入 |
|
||
| `cache.mjs` | 轮廓、材质和静态 UI 缓存及失效 | 不持有第二份玩法状态 |
|
||
|
||
数据流为:**关卡和路径 → 现有规则结果 → 表现场景 → 几何与布局 → 分层绘制 → 主 Canvas 合成**。触摸经同一布局逆变换回到原规则坐标。
|
||
|
||
### 2.3 保留快照来源的接入方法
|
||
|
||
1. 保持 `src/upstream` 快照及其来源哈希不变。在本地新增构建适配模块,扩展现有 `build.mjs` 的 UI 变换。
|
||
2. 首先建立明确的“几何准备/绘制/UI 回写”接缝,再委托新 renderer 绘制。保留原输入、求解、存档、提示控制器、通关及教学业务。
|
||
3. 构建变换以明确入口与预期匹配次数检查,入口不符直接构建失败。禁止对全部 `fillStyle` 或颜色字符串做无范围替换,也不运行时拦截 Canvas API 猜语义。
|
||
4. 主题开关放在构建配置,支持旧皮肤与新皮肤对照;第一阶段不增加玩家设置项。
|
||
5. `renderLesson` 必须使用同一 renderer;预览调用的临时状态要完整保存和恢复,新增场景及缓存状态也必须隔离,避免教学修改玩家棋盘。
|
||
6. 构建变换模块与快照哈希一起纳入回归。未来如接入新上游,先检查接缝,再更新变换。
|
||
|
||
不直接依靠只读 `variantSnapshot()` 重建整个正式渲染:它当前不包含完整轮廓、共边入口和文字保留区。应由同一几何准备过程向棋盘、提示和教学输出共同的 Scene 数据。
|
||
|
||
## 3. 几何:先保证“一整块只算一步”
|
||
|
||
### 3.1 分开管理三种几何
|
||
|
||
| 几何 | 用途 | 约束 |
|
||
|---|---|---|
|
||
| 逻辑几何 | 原有命中、相邻、阻挡和手势插值 | 按原规则;皮肤不扩大相邻重叠触点 |
|
||
| 显示轮廓 | 缩缝、圆角、底沿、材质 | 不反馈给规则判定 |
|
||
| 信息安全区 | 数字、奇偶、类别、通道、提示避让 | 基于实际文字边界和轮廓内距生成 |
|
||
|
||
单元边、块 ID、共边入口全部保留稳定标识。显示轮廓按关卡和布局生成一次,按压动画只改变表现变换。
|
||
|
||
### 3.2 矩形与异形轮廓算法
|
||
|
||
1. 从 `units(c)` 获取占用单位格;每格生成定向四条边,共享内部边抵消。
|
||
2. 连接剩余有向边,遍历所有闭环;按包含关系识别外环与内孔,统一绕向,删除共线点。
|
||
3. 同一块的单位格先形成完整轮廓,再缩进、倒角、投影。任何中间单位格线都不进入材质绘制。
|
||
4. 面轮廓向块内缩进 `inset = 0.045u`,凸角半径 `clamp(6, 0.18u, 12)`;凹角最多 `0.06u`,窄凹口可保持直角。
|
||
5. 正交轮廓按边法线偏移并求相邻偏移边交点,限制尖角与短边;检查偏移后自交、环消失和细颈收缩。失败时先减小局部圆角和缩进,仍失败则使用保拓扑直角轮廓。
|
||
6. 外环与内孔反向绕制,用基础非零绕数填充和裁切;目标宿主需做内孔自检。若目标不满足裁切行为,独立离屏遮罩擦出内孔后合成,不能擦除主画布已有内容。
|
||
|
||
矩形走专用圆角矩形快路径。禁止对 L、T、S 等异形逐单位格画圆角矩形,那会产生内部缝和多份阴影。棋盘块之间围成的空洞与“单块自身内孔”分别测试,后者只有经内容审计确认存在时才作为当前内容覆盖项。
|
||
|
||
### 3.3 六边形
|
||
|
||
沿用当前轴向坐标到竖屏顶点的转换。当前 renderer 的 `unit` 是外接半径缩放量,视觉用的六向中心距为 `uHex = √3 × unit`;材质和文字比例统一使用 `uHex`。
|
||
|
||
从实际顶点包围盒求适配比例;圆角上限 `0.11uHex`。墙门和桥仍取未圆滑的真实共边,不能把 q/r 范围当矩形宽高,不能用缩圆后的外轮廓推导邻接。
|
||
|
||
### 3.4 数字锚点
|
||
|
||
普通矩形保留整体中心;异形以现有占用单位格安全锚点为起点,再检查整组文字矩形是否留在块内。候选点按离中心距离、到外环/内孔距离、与墙门及通道的间隔排序;候选选择与 ID 稳定绑定。
|
||
|
||
同一关锚点固定,访问前后数字不跳位置。若完整信息组放不下,切换预定义密集排版;必要说明移至固定反馈栏。不得仅检查中心点在块内,就认定两位数和角标一定可放下。
|
||
|
||
## 4. 材质:用二维叠层表现轻厚度
|
||
|
||
### 4.1 每块的绘制配方
|
||
|
||
| 通道 | 实现 | 起始参数 |
|
||
|---|---|---|
|
||
| 接触投影 | 整块轮廓的短投影,静态或材质缓存时生成 | x0、y3、blur5、墨色10% |
|
||
| 底沿 | 完整轮廓向下平移后实色填充,再由面覆盖 | `h=clamp(2,0.055u,4)` |
|
||
| 正面 | 同一轮廓填充,中心文字区域尽量纯色 | 奶油/紫/类别面 |
|
||
| 有效边界 | 清楚的连续描边 | 1.25,密集态1.5 |
|
||
| 左上倒角 | 只强调朝光侧的内侧轮廓段,裁切于面内 | 0.75–1;紫块用 `primaryEdge` |
|
||
| 右下收边 | 低强度暗边,必要时省略 | 不能叠成第二圈厚黑边 |
|
||
|
||
未走面 `#FFF8EA`、底沿 `#D8C4A0`、边界 `#8A7660`;标准已走面 `#6552D9`、底沿 `#49379E`。蓝橙类别块保持原类别面,访问仅增加紫内框和桥。
|
||
|
||
先按轮廓绕向确定外法线,再与左上光方向做点积选择受光边。圆角亮边用路径分段近似,端部淡化;不把整个块复制一层白描边。块面可选线性微渐变,各 RGB 通道变化不超过6,不用逐像素噪声、法线贴图或实时模糊制造质感。
|
||
|
||
投影用于接触感,边界负责可读性。全板先画底沿和投影,再画所有块面,避免后一块阴影压在前一块数字上。内孔处的底沿也按相同上下关系裁切,不填平孔洞。
|
||
|
||
### 4.2 桥接应成为积木的一部分
|
||
|
||
桥只出现在玩家实际连续访问、规则允许跨越的共边上,宽度取 `0.42u`,六边使用 `0.42uHex`,并受有效共边长度限制。
|
||
|
||
- 合并连续共线的单位共边,去掉端点安全距;多段共边按实际入口选择,选定后保持稳定。不能无条件取 `sharedSegments()[0]`。
|
||
- 取共边中点和法向构造短胶囊,沿法向长度覆盖两侧缩进及少量重叠;不拿两块数字中心直接相连充当实体桥。
|
||
- 绘制桥底沿和面,与块面小幅重叠以消除抗锯齿裂缝;隐藏被桥穿过的局部边界和亮边,保留其他外边界。
|
||
- 桥厚度动效仅在沿共边方向展开,跨缝方向始终连通;墙保持可见,锁定开启门保留框与扣件。
|
||
- 双色关桥可用紫色,但只覆盖桥本身,不能涂满两端类别面。
|
||
|
||
桥的连接关系来自逻辑,材质动画不会让一条非法边看起来可通过。
|
||
|
||
## 5. 状态、规则符号与提示合成
|
||
|
||
### 5.1 用组合状态替代单一颜色
|
||
|
||
每块至少分开持有:类别、已访问步号、固定要求、通道状态、冲突、当前末端、提示保留区。场景引用规则给出的墙门状态;这些字段共同决定绘制通道。
|
||
|
||
| 状态组合 | 块面和数字 | 附加表现 |
|
||
|---|---|---|
|
||
| 普通未走 | 奶油面,固定条件深墨字 | 固定条件内框 |
|
||
| 普通已走 | 紫面白步号 | 深紫底沿、桥 |
|
||
| 类别已走 | 蓝/橙面深墨步号 | 圆/三角、2单位紫内框 |
|
||
| 固定要求已满足 | 沿所属访问态 | 条件框保持,以适配底色的浅/深色呈现 |
|
||
| 普通冲突 | 深红面,实际步号 | 叹号和具体要求;反馈栏说明 |
|
||
| 类别冲突 | 保留类别面与形状 | 红色局部角标和边;不整面染红 |
|
||
| 当前末端 | 沿所属访问态 | 一组短焦点角标 |
|
||
| 提示 | 保留全部底层状态 | 独立白芯深边轨迹 |
|
||
| 完成 | 保留最终基础颜色和数字 | 外围短扫光、对勾与完成文案 |
|
||
|
||
空路径的固定1仍要清楚标识起点;表现模型将“起点条件”和“已访问”分开,计数、桥和实际步号完全依据玩家路径。
|
||
|
||
### 5.2 规则符号的程序实现
|
||
|
||
| 元素 | 几何做法 | 排版与语义 |
|
||
|---|---|---|
|
||
| 奇偶 | 字体绘制“奇/偶”+条件框 | 已走后数字在上,奇偶在下,副标目标11–12 |
|
||
| 通道 | 端口到中心的折线路径,浅衬线+深槽线 | 六种方形直/弯通道,可反向,无箭头;数字右上 |
|
||
| 类别 | 实心/描边圆与三角 | 持续可见;与通道组合时类别左下 |
|
||
| 永久墙 | 真实共边上的深墨连续条带,裁切黄色短斜线 | 宽6–8;不使用虚线代替实体阻挡 |
|
||
| 关闭门 | 两侧端框+中间连续棕色门片 | 附“关”,挡条连续 |
|
||
| 开启门 | 保留端框,门片收向两侧 | 中间明确留空,附“开” |
|
||
| 已穿门 | 开口+固定扣几何 | 可读“已过”;回退由规则恢复 |
|
||
|
||
通道位置由真实端口方向决定,中心数字与通道分区。非常密集时优先保留数字、类别和开口形态,将冗余解释移到反馈栏,不把全部信息缩成难辨的小点。
|
||
|
||
六边版只渲染实际数据支持的机制;若后续增加六向通道,应补六向端口合同,不能直接套用当前四向 `l/r/u/d` 绘制函数。实验转墙只接六边原型,不加入当前200关皮肤范围。
|
||
|
||
### 5.3 正式绘制顺序
|
||
|
||
| 顺序 | 内容 |
|
||
|---|---|
|
||
| 1 | 暖黄背景、外围静态纹样、舞台 |
|
||
| 2 | 全板块体与桥的投影、底沿 |
|
||
| 3 | 块面、桥面、有效轮廓及局部倒角 |
|
||
| 4 | 类别、条件框、通道、数字、当前位置、局部错误 |
|
||
| 5 | 独立提示层,先做遮罩和语义避让后合成 |
|
||
| 6 | 最终墙门及必要语义补绘 |
|
||
| 7 | 导航、反馈、操作按钮、弹窗 |
|
||
|
||
提示遮罩是必要条件;只把底层数字画在上面没有用,因为独立提示 Canvas 会更晚合成。
|
||
|
||
### 5.4 提示升级
|
||
|
||
保留当前分段提示的请求、段末消失、偏离、撤销恢复行为;只升级显示路线和遮罩。
|
||
|
||
1. 路线按“块内引导点 → 合法共边入口 → 下一块内引导点”构造。异形内部折线限制在所属块的占用区域内,必要时在占用单位格图上寻路;这是提示画线,不改变玩家规则。
|
||
2. 已走块遮罩取完整显示轮廓,并包含底沿和抗锯齿安全边;已走桥也加入遮罩。覆盖错误路径的已走块同样擦除,不能只擦正确前缀。
|
||
3. 数字、条件副标、类别、通道核心和墙门各输出文字/图形保留区。提示路径绕行或切段;光点与端点环采用相同裁切。
|
||
4. 提示全程只改透明提示层;`destination-out` 只能在此层或专用遮罩层执行,不用于擦除主画面。
|
||
5. 白芯4–7,深色外线总宽再增3–4;透明度与底色合成后复核。减少动态采用持续静态虚线,保留整段信息。
|
||
|
||
优先从真实共边生成引导路线,避免中心连线跨出 L 形块、穿过空洞。数字处允许线段中断,不为追求连续发光而遮挡关键要求。
|
||
|
||
## 6. UI、文字和屏幕适配
|
||
|
||
### 6.1 通用组件
|
||
|
||
背景默认 `#FFE69A`,可选底端 `#FFDE79`;舞台 `#FFF6DF`。背景仅生成3–5个静态圆、圆角方框、三角轮廓和弧线,使用关卡/页面稳定种子,避免每帧随机闪变;棋盘与操作区周围保留净区。
|
||
|
||
按钮由圆角路径、底沿、图标路径和文字构成。主按钮紫面白字,次按钮奶油面深墨字;常规高64、圆角18,紧凑高52、圆角14。按下表面下移1单位,底沿变浅,触点和布局不动。重开/撤销/指路按当前微信能力显示,完成后同一区域替换下一关。
|
||
|
||
功能图标统一24单位母版、2–2.5笔画:重开用回转弧+箭头,撤销用左回箭头,指路用圆弧灯泡+短光线,设置用齿轮路径,选关用圆角网格,对勾用两段折线。绘制前统一缩放与设置圆端点,颜色从语义令牌取。禁止使用 Emoji 代替正式图标,以免平台外观不同。
|
||
|
||
选关卡片、弹窗、规则教学共用组件。新增首页属于全页面阶段;现有微信包起始选关页并不等于已经有独立首页。新开关必须接线、持久化并通过生命周期检查后才显示。
|
||
|
||
### 6.2 字体选择
|
||
|
||
正式目标采用 Nunito 800 数字和 Noto Sans SC 中文。先清点实际使用汉字与字号,按许可交付所需字集及声明;不能根据字体名称就假设宿主已经可用。
|
||
|
||
字体加载属于平台适配工作,实施时核对目标基础库支持的加载方式和路径约束。进入对局前完成关键字形准备;若失败,使用明确回退并一次性完成测量,避免解题中途换字体。数字0–9也可制作原创贝塞尔轮廓,支持1–36拼排,维持一致字形;中文仍保留文字排版能力,不逐句做成轮廓。
|
||
|
||
路径命令、文字测量缓存和离屏绘制均不需要生产图片资源。首页品牌首版可用标题文字叠绘米白外缘、短底沿与珊瑚/紫主字;原创轮廓精修列为P2,避免把标题制作变成首个技术阻塞点。
|
||
|
||
### 6.3 自适应和统一坐标
|
||
|
||
矩形按占地包围盒计算 `u = min(stageInnerW/C, stageInnerH/R, 64)`,优选56;根据内容和屏幕进入密集布局。当前代码允许96/110的放大上限,要在新皮肤布局中改成设计报告的限制。
|
||
|
||
7列36块盘面:375宽采用外边距12、内边距8时净宽335,`u≈47.9`;320宽同策略净宽280,`u≈40`。后者需要真机检查,不能承诺全部达到44触点。
|
||
|
||
固定顶栏、反馈和底部操作区,舞台使用剩余高度。常规单数字约 `0.50u`、两位数约 `0.44u`;低于报告目标字号时输出布局诊断,不默默缩到不可读。
|
||
|
||
`Layout` 同时输出舞台原点、缩放、UI矩形和逆变换。同步修改当前 `event()` 中硬编码的 `top+82`,以及棋盘合成位置和尺寸;这三处必须取同一份布局。DPR只决定 backing store 清晰度,不能重复进入触摸坐标和逻辑单位。
|
||
|
||
## 7. 动效与运行调度
|
||
|
||
| 事件 | 时间与表现 | 规则/输入约束 |
|
||
|---|---|---|
|
||
| 按钮 | 80ms按下、120ms恢复,最多0.98缩放 | 点击即时生效 |
|
||
| 落格 | 140ms,0.985压低后最高1.015回稳 | 固定命中;窄异形/墙门附近只变亮边 |
|
||
| 桥接 | 120ms扩展宽度 | 不出现暂时断路 |
|
||
| 数字 | 100–120ms淡入 | 固定条件持续可读 |
|
||
| 撤销 | 100ms残影淡出 | 路径立即回退,批量撤销不串行等待 |
|
||
| 错误 | 200ms红角/边强调 | 墙挡后末端不动,不全屏摇晃 |
|
||
| 门 | 160ms门片收拢/展开 | 连续输入合并到最新目标状态 |
|
||
| 完成 | 总计320ms外缘扫光,完成反馈500ms | 下一关可手动点击,不按块逐个等待 |
|
||
|
||
统一使用当前时刻求进度,采用设计令牌中的缓出曲线;新事件从当前视觉值过渡到新目标,旧门动画不排队。形变围绕稳定锚点,底沿与亮边一起响应。
|
||
|
||
减少动态时取消缩放、抖动、光点和粒子,门直接显示最终形态。退后台取消 RAF 和临时动效,回前台按最新玩法状态重建,清除过期动画;沿用当前音频中断管理,不额外合成声音。
|
||
|
||
当前主循环每帧全屏绘制,棋盘自身还会重设 Canvas 尺寸。新方案改为脏状态触发:输入、布局、页面、提示时间或动画进度变化才更新。无活动动效时停止 RAF;反馈自动消失、字体完成等异步变化显式标脏,不依赖常驻循环才看得到变化。
|
||
|
||
## 8. 缓存、兼容与性能预算
|
||
|
||
### 8.1 分层缓存
|
||
|
||
| 缓存 | 键/失效条件 | 策略 |
|
||
|---|---|---|
|
||
| 本地轮廓与真实共边 | 内容修订、几何ID | 与颜色和访问态无关 |
|
||
| 屏幕几何和信息区 | 舞台尺寸、缩放、字体、密度档 | resize与字体准备后重建 |
|
||
| 材质轮廓或小块缓存 | 轮廓、u、DPR、面类别、质量档、主题版本 | 惰性生成,有总量上限 |
|
||
| 静态背景和UI | 页面、尺寸、主题、文字 | 状态变化时更新 |
|
||
| 教学预览 | 教学关、尺寸、主题 | 不复用玩家可变Scene |
|
||
|
||
首版无需为每块每种状态建缓存,也不必每层创建全屏 Canvas。数字和墙门动态绘制,只有测量数据支持时才进一步缓存。Canvas宽高只在尺寸/DPR真正变化时赋值,避免每次落格重新分配并清空状态。
|
||
|
||
375×812、DPR3的全屏RGBA表面原始像素约10.45MiB,三张全屏表面约31.36MiB,尚未计宿主副本和其他内存。棋盘/提示按实际区域分配,缓存计数加上字节估算;质量降级先关模糊与粒子,再降低非关键层缓存分辨率或DPR,避免常驻大量全屏离屏层。
|
||
|
||
### 8.2 平台实现约束
|
||
|
||
基线采用项目已经使用的 `beginPath`、`lineTo`、`quadraticCurveTo`、`arc`、`fill`、`stroke`、Canvas合成方式。轮廓缓存为普通路径命令数组,重放到 context;不把 `Path2D`、原生 `roundRect`、滤镜或某种额外离屏接口作为必需前提。
|
||
|
||
新增裁切、渐变、投影和字体加载在微信目标环境逐项自检。原生投影若成本高或显示不一致,可用缓存时生成的2–3层低透明度短偏移轮廓近似;降级仍保留实色底沿与有效边界。每次绘制通道用 `save/restore` 隔离裁切、透明度、混合方式和虚线状态。
|
||
|
||
### 8.3 度量目标
|
||
|
||
目标是常规设备稳定60fps;低性能档可评估稳定30fps。绘制CPU耗时建议以P95低于8ms为首轮目标,并同时记录整帧耗时、输入到首次可见反馈、缓存字节数与重建次数。这些是待测目标,不能由桌面Canvas或模拟微信测试推导真机达标。
|
||
|
||
密集盘快速连画、分段提示、教学动画分别记录;纯思考阶段应无持续绘制。降级永远不删除墙门、数字、条件框、类别和提示信息。
|
||
|
||
## 9. 制作顺序与交付门槛
|
||
|
||
| 阶段 | 实际工作 | 交付门槛 |
|
||
|---|---|---|
|
||
| A 技术骨架 | 主题读取、布局统一、渲染接缝、几何与Scene | 原有行为保持,快照不变,教学状态隔离 |
|
||
| B 黄金样张 | 用真实关卡生成基础、大块、异形、通道、双色、门及密集盘 | 面、底沿、桥和文字在复杂盘面清楚 |
|
||
| C 交互单关 | 落格、连画、逐格回退、撤销、提示、门动画 | 输入即时,提示不改玩家填色 |
|
||
| D 全页面 | 选关、对局、规则、完成;按范围新增首页与设置 | 窄屏、胶囊、安全区、按钮布局通过 |
|
||
| E 全内容与平台 | 200关自动回归、视觉抽样、真机性能与生命周期 | 新皮肤独立产出验证记录,才进入发布 |
|
||
|
||
P0:真实轮廓、规则信息、类别保留、桥接、提示遮罩、输入坐标。
|
||
|
||
P1:完整轻厚度材质、UI字阶、字体、局部动效、缓存调度。
|
||
|
||
P2:首页原创字形精修、少量通关纸片。首版只做暖黄主题,不为200关逐关做美术资源。
|
||
|
||
建议先交付“6类真实关卡的可交互样张页”,共用正式 renderer,以配置切换主题、尺寸、减少动态与质量档。该页是开发验收工具,不进入玩家流程。预览和QA截图可以导出用于检查,但不可反向成为运行时游戏资源。
|
||
|
||
### 9.1 验收矩阵
|
||
|
||
| 验收项 | 方法与通过条件 |
|
||
|---|---|
|
||
| 无图片美术依赖 | 审查运行包和加载调用;没有作为游戏美术使用的位图、图片图集或外部SVG |
|
||
| 几何与大块 | L/T/S、凹口、空洞样张;一块一次,内部无格线,轮廓无自交;桥不穿墙 |
|
||
| 数字与组合 | 10/11/17/20/28/36、奇偶、通道、类别组合;保留区互不覆盖 |
|
||
| 提示 | 比较开提示、撤销重画前后的已走面采样;基础填色相同,提示避开数字与通道 |
|
||
| 门 | 空盘、落格、穿过、回退、重开;形态与 `doorOpen/doorLatched` 一致 |
|
||
| 适配 | 320×568、375×667、390×844、414×896;至少含 r2-163/r2-187 |
|
||
| 手势 | 快画、慢画、抬手续画、逐格退回、撤销、重开;屏幕位置与命中一致 |
|
||
| 教学和弹窗 | 正式renderer复用,关闭后玩家路径/提示/坐标/存档不变 |
|
||
| 动效生命周期 | 后台、返回、旋转/尺寸变化、减少动态;没有积压动画和状态漂移 |
|
||
| 内容和构建 | 全关唯一解和原有输入回归通过;快照哈希与适配入口检查通过 |
|
||
| 真机表现 | 同时记录视觉、帧耗时、内存估算、音频与触摸;浏览器截图不当作微信实测 |
|
||
|
||
### 9.2 后续实施时复用的检查命令
|
||
|
||
以下在仓库根目录执行,命令沿用现有工程;本次文档编写未执行新皮肤测试。
|
||
|
||
```powershell
|
||
node docs/design/bright-classroom/audit-design.mjs
|
||
Push-Location wechat-campaign-200-r2
|
||
node build.mjs
|
||
node --test hints.test.mjs lessons.test.mjs audio-copy.test.mjs
|
||
node smoke.mjs
|
||
Pop-Location
|
||
```
|
||
|
||
`build.mjs` 当前依赖本仓库原型内的 esbuild 安装;`smoke.mjs` 会读取manifest指定的上游来源路径。实施前检查这些依赖,缺失时修正可复现环境,不能把路径错误当成皮肤问题。原有颜色与采样断言需要主题参数化,同时保持“提示前后不改变玩家填色”的不变量,不能简单删除失败断言。
|
||
|
||
新增有实际价值的验证集中在多环轮廓、窄凹口退化、真实共边入口、信息区碰撞、教学Scene隔离、坐标正逆变换及提示像素不变量;颜色常量和简单绘制包装无需逐项写镜像测试。
|
||
|
||
## 10. 依据、结论和执行路径
|
||
|
||
下表是本方案的 Evidence → Finding → Path,对应本地文件,可从仓库根目录用 `Get-Content -LiteralPath <路径>` 复核;未以未运行的原型或真机截图作为证据。
|
||
|
||
| 证据 | 已观察事实 | 技术结论 | 执行路径 |
|
||
|---|---|---|---|
|
||
| E01:[完整美术报告](2026-10-21_美术设计-明亮教具室-report.md)及[令牌](design/bright-classroom/tokens.json) | 暖黄、奶油、轻厚度、明确规则和版本边界 | F01:程序化材质与语义分层,材质服从读盘 | P01:主题→材质→复杂关样张 |
|
||
| E02:`wechat-campaign-200-r2/src/upstream/ui.mjs` | 现有Canvas几何、块、桥、墙门和UI回写 | F02:可复用Canvas,但不能只改颜色或删除draw业务 | P02:渲染接缝→Scene→新绘制通道 |
|
||
| E03:`wechat-campaign-200-r2/src/upstream/rules.mjs` | 占用格、单环轮廓、共边、门和判定 | F03:显示需补多环与安全偏移,规则仍沿用原结果 | P03:边抵消→闭环→缩进倒角→共边入口 |
|
||
| E04:`wechat-campaign-200-r2/src/hints.mjs`、`src/main.mjs` | 透明提示层、中心连线、玩家单位格擦除、延后合成 | F04:升级引导路线、完整遮罩和信息避让 | P04:统一几何→提示切段→像素不变量 |
|
||
| E05:`wechat-campaign-200-r2/build.mjs`与README | 上游快照有哈希;构建注入教学与宿主 | F05:皮肤采用可检查的构建适配,教学复用同一renderer | P05:入口断言→构建→教学隔离→整包回归 |
|
||
|
||
第一项可验收工作应是:用真实大块/异形关和一个密集组合关,在当前微信宿主中跑通“完整轮廓+轻厚度+桥接+数字+提示遮罩”,并保持原有操作。通过后再铺开全页面,最终以200关回归与微信真机记录判定是否可以交付。
|