Files
HexTrails/Design.md
T

190 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HEX TRAILS 设计规范
版本:2.0 · 2026-09-08 · 适用:网页、手机触摸界面与 Cocos 移植。
本文件规定设计角色和使用方式;`src/design-tokens.js` 是颜色数值的唯一来源。修改数值后运行 `npm run design`,同步生成 CSS、JSON、面板 PNG、对比度报告和可视化手册 `Design.html`。HTML 为单文件离线版本,包含原始图片、色值复制、组件示例、弹窗动效与本文全文。新界面不得另写一套 HEX 或用滤镜临时拼配色。
## 1. 设计方向
**清爽、明快、易读的哑光解谜游戏。** 环境使用按难度或活动组织的低饱和主题色,棋盘采用暖白,主操作采用紫色。全局建立 12 色棋子库,单关默认使用其中 7 色,支持 4 / 7 / 9 / 12 色对照;高饱和度不平均分配给每一个按钮。
- 棋子是第一视觉焦点,Level 和步数是第二层,工具是第三层。
- 纯色背景,无纹理、光晕、装饰圆盘。底板要看得出六边形分格。
- 棋子保持正顶视角、六边等长、小圆角;无侧面厚度和凹槽。
- 图标采用用户选定的**生成图集原始造型**,不得静默替换为另一套代码图形。
- 扁平面板搭配生成图标;保留图标原图细节,不用黑化、白化滤镜重塑外观。
## 2. 成熟模式如何用于本项目
采用 Material Design 3 的**语义颜色角色**:先定义颜色承担的职责,再给组件绑定角色;`primary / onPrimary`、`surface / textPrimary` 成对使用。采用层级明确的表面和主次操作,避免每个工具都争夺视觉注意力。[Material 3 主题与颜色角色](https://developer.android.com/codelabs/m3-design-theming?hl=en)
采用 W3C 的对比度方法作为验收约束:普通文字至少 4.5:1,大号文字和必要的非文字视觉标识至少 3:1。颜色之外还要用文字、图标、位移或选中标记表达状态。[文字对比度](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html) · [非文字对比度](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html)
这些来源提供方法和约束;下面的 HEX、游戏形态、动效时长是本项目的设计选择,并非 Material 官方游戏模板。当前有四套主线主题与一套每周挑战美术主题,不随系统壁纸自动换色。主题只改变美术表现,不改变难度判定。
## 3. 颜色体系
### 3.1 环境与内容
| Token | 色值 | 用途与配对 |
|---|---|---|
| `background` | `#A8BECF` | 基础回退色;游戏场景使用下表主题背景与场景文字色 |
| `board` | `#F2EEE5` | 棋盘底格,暖白区分冷色背景 |
| `boardGrid` | `#89867D` | 六边形边界,细线且清楚可见 |
| `track` | `#435F78` | 深蓝轨道中心线,线宽 `max(2.5px, 格子半径 × 0.10)` |
| `trackHalo` | `#F2EEE5` | 轨道浅色外缘,不能盖断接头 |
| `surface` | `#F7F6F2` | 弹窗与编辑面板 |
| `textPrimary` | `#273B50` | Level、步数、标题、主要标签 |
| `textSecondary` | `#314A5F` | 说明与次要标签;用字号和字重区分层级 |
辅助文字不能通过大幅降低透明度来变淡。小字必须用规定的文字色,不使用旧版的浅紫灰。棋盘与背景的区别还包括完整轮廓、清晰分格和轨道,不只依赖色相差。
### 3.2 操作与状态
| Token / 配对 | 色值 | 用法 |
|---|---|---|
| `primary / onPrimary` | `#6652B8 / #FFFFFF` | 下一关、试玩、主要确认、当前选中关卡 |
| `secondary / textPrimary` | `#E4EAF0 / #273B50` | 重玩、普通选关、编辑器次级动作 |
| `utility / onUtility` | `#52697E / #FFFFFF` | 选关、设置、撤销、重来、提示的图标底板 |
| `selection / onSelection` | `#DFD9F3 / #3F327A` | 可扩展的弱选中状态 |
| `warningSurface / warning` | `#F9E3D2 / #A44825` | 阻挡、导入失败、不可解提示 |
| `reward` | `#B9760C` | 星星轮廓与奖励强调,限制面积 |
| `input / textPrimary` | `#FFFFFF / #273B50` | 输入框、选择框 |
| `disabled / onDisabled` | `#CBD4DD / #526579` | 原生移植的禁用表面和文字参考 |
| `scrim` | `#273B50`,透明度 48% | 模态遮罩,背景模糊 5px |
| `focus` | `#3F327A` | 键盘焦点外框 |
一张弹窗只安排一个高强调主操作。工具按钮统一用蓝灰底板,不再分别使用蓝、粉、黄。提示无需绿色“免费”角标;现有角标沿用中性表面。成功不额外引入薄荷绿,使用主操作色和星星表达。
编辑器的工具、方向、旋转和文件操作同样使用 `utility / onUtility`,保证生成白色图标在底板上可辨认;选中工具与试玩使用 `primary / onPrimary`。
### 3.3 棋子色与图片事实
棋子颜色不代表功能、品质或阵营。原有四枚棋子来自已接受的图片;以下是采样区域中心的代表值,图片像素允许存在小幅变化:
| Token | 代表色 | 方向箭头 |
|---|---|---|
| `tileBlue` | `#2392FD` | 白色 |
| `tilePink` | `#FC3E80` | 白色 |
| `tileYellow` | `#FDBC28` | 深蓝灰 `textPrimary` |
| `tilePurple` | `#874FFD` | 白色 |
黄色上的白箭头对比不足,因此使用深色箭头。所有棋子均可通过方向箭头、位置和运动判断,不要求辨认颜色才能通关。未经用户确认,不重新生成或调色替换已接受的棋子。
### 3.4 场景主题与 12 色库
互动展示:在本地开发服务打开 `/design-showcase.html`,可切换主题、点击真实棋盘、播放离场效果与慢速观察。展示中的五套主题使用同一关,便于比较色彩。
| 难度 / 场景 | 主题 | 环境色 | 棋子搭配 |
|---|---|---|---|
| 轻松 0–29 | 薄荷浅湾 | `#C5E4DF` | 晴空蓝、湖水青、日光黄 |
| 进阶 30–49 | 杏色午后 | `#F1D7B8` | 珊瑚橙、鸢尾蓝、湖水青、蜜桃杏 |
| 烧脑 50–69 | 鸢尾花园 | `#D8D0EB` | 葡萄紫、嫩芽绿、玫瑰红、冰川青 |
| 挑战 70–100 | 玫瑰暮色 | `#E7C3CE` | 玫瑰红、鸢尾蓝、日光黄、兰花紫 |
| 每周挑战美术预览 | 午夜极光 | `#293956` | 冰川青、兰花紫、日光黄、莓果粉 |
四套浅色背景使用 `textPrimary` 场景文字;午夜背景使用 `surface` 色文字。弹窗内部继续使用暖白底和深色文字,避免场景文字色污染组件。每周挑战目前提供独立美术主题和预览入口,尚未接入周赛、排行榜或活动日历。
新增八色:湖水青 `#008B83`、珊瑚橙 `#EF704F`、嫩芽绿 `#91C95B`、鸢尾蓝 `#5267CF`、玫瑰红 `#C83F66`、蜜桃杏 `#F5AA83`、冰川青 `#58C9D5`、兰花紫 `#AE64C7`。前四色保留已接受的图片采样;新增色使用同一圆角六边形轮廓进行纯色绘制,没有改动原始图片。
`PIGMENTS` 与 `LEVEL_THEMES` 在 `src/design-tokens.js` 中维护,并导出到 `design/tokens.json`。箭头按实际色值选择白色或深蓝灰,最低对比度 3:1。主线默认将主题色组扩展为 7 色,URL 参数 `colors` 支持 4、7、9、12;主题表中的配色作为起始色,优先补足差异较大的色相。主线按初始棋子顺序循环分配主题色组,因此移走棋子、旋转和撤销不会让剩余棋子变色。编辑器开放完整 12 色库,自由创作不强制收敛。
颜色不代表功能、品质或阵营;难度也必须保留文字,不只靠背景判断。主题切换只发生在换关或主动预览时,不随剩余步数改变。背景保持纯色,用色彩变化建立旅程感。
### 3.5 禁止的搭配
- 白色小字放在黄色、浅蓝灰或浅绿色按钮上。
- 使用同样的浅灰同时承担背景、底板和轨道。
- 紫色选中、绿色确认、黄色提示、粉色重来同时作为同等级操作。
- 用 `brightness / invert / saturate` 临时调面板色;这样无法核对实际颜色。
- 将语义警告色铺满常规棋盘,或只通过红色表示阻挡。
## 4. 组件规范
### 游戏主界面
游戏顶部恢复居中关卡计数,左侧选关、右侧设置;剩余步数位于其下方,不显示主题说明。棋盘视口占据顶部状态与底部紧凑操作栏之间的全部空间,不再限制为正方形。底部仅排列撤销、重来、提示;左右转恢复大箭头,悬浮于棋盘下部两侧,不占据额外布局高度。缩放按钮与常驻手势说明不占用棋盘空间;保留双指缩放、放大后拖动及桌面组合键滚轮。左侧选关,右侧设置。没有 Logo、关卡副标题、难度、待离场数量、角度读数或底部导航。
旋转操作为放大的生成箭头,下方分别写“左转”“右转”,不加矩形底板。文字用主文字色;白色箭头允许轻微蓝灰轮廓阴影增强边缘识别,不能改写原图轮廓。它们须保留至少 44×44 的触摸区域。
撤销、重来、提示使用相同的工具底色和图标规格,下方标签不少于 12px。禁用时确实停止操作,网页透明度为 55%;不得只有颜色变化却仍可点击。
### 棋盘和轨道
大棋盘测试支持边长 6(轴向半径 5,91 格)与边长 7(半径 6,127 格)。网页棋盘支持以双指中点为锚的 1–4 倍缩放,放大后单指拖动;双指手势及其余指抬起不触发棋子点击。100% 视图保留原有边缘拖动旋转,放大后用左右按钮旋转。桌面提供 Ctrl/Command + 滚轮缩放;收拢双指或缩小回 100% 恢复全盘视图。缩放与绘制、点击共用同一坐标变换,不改变规则坐标。
先画全部底格,再画分格线,再统一画轨道外缘与中心线,最后画棋子。相邻格子连接端口必须完全重合。内部不留透出背景的缝;外边缘需为线帽预留空间。分格线宽取 `max(1px, 格子半径 × 0.024)`。
棋子保持微小圆角。所有游戏运动、碰撞和绘制使用同一坐标体系。图片只能在原图不透明、无杂点的区域采样;不得带入棋盘格底纹或透明噪点。
### 弹窗
所有弹窗使用暖白表面,标题主文字色、正文辅助文字色。主按钮紫色配白字,次按钮中性表面配深字。正文推荐 13–14px、行高 1.75;弹窗圆角 24px、左右留白至少 24px。
弹窗必须是真正的模态层:使用 `showModal()`,背景变暗并模糊,鼠标、触摸和键盘均不能操作后方控件。结果弹窗不能通过点击背景意外消失;下一关或重玩后关闭。设置/选关允许点击外部关闭,但该次点击不可传给后方按钮。
选关数字与难度说明保留,当前关卡使用主操作色,并附当前状态。未通关不以灰到不可读的文字表示。
## 5. 图标与图片资产
| 内容 | 当前资源 | 使用规则 |
|---|---|---|
| 生成图标 | `assets/ui-icons-generated.png` | 原始生成图的逐字节副本,1254×1254 |
| 图标裁切 | `src/ui-skin.js` 中 `ICONS` | 按主图形测量,四周留白后裁成正方形并居中 |
| 面板颜色 | `assets/ui-surfaces.png` | 从 token 输出的纯色 PNG,13 个 32×32 色块 |
| 棋子 | `assets/tiles-matte-clean-v8.png` | 中央干净色块采样 + 共用圆角正六边形遮罩 |
图标生成源文件:`exec-64bcb2ee-fa31-48f9-9a7e-3e2c8c327520.png`。这一套包括选关、设置、左右转、撤销、重来、提示、星星等。`ui-icons-flat.png` 是此前代码重绘版,保留作历史文件,**不再被当前界面引用**。
面板仅采样每个色块中央的 28×28 区域,四周预留 2px,防止放大和双线性过滤时混入相邻色块。
不重绘用户已选图标、不换形状、不强制黑白化。当前白色图标置于 `utility` 底板上;旋转箭头和星星可用 token 定义的轻微轮廓阴影。正方形 SpriteFrame 等比显示,不能把窄图标拉宽。SVG 和 Unicode 字符不得临时顶替正式图标。
生成原图透明区仍可能有细小边缘噪点;当前做的是主图形裁切,未宣称对原 PNG 完成像素级清理。若实机仍可见噪点,应清理同一素材并重新验收,不能静默更换图标系统。
## 6. 字体、间距与形状
| 层级 | 规格 |
|---|---|
| Level | 28px,粗体,居中 |
| 剩余步数数字 | 32px,粗体,居中 |
| 弹窗标题 | 24px,粗体 |
| 正文 | 13–14px,行高 1.75 |
| 操作标签 | 12–13px |
| 次要说明 | 至少 11px;不靠低透明度弱化 |
使用当前圆润系统字体回退栈,中文优先 PingFang SC / Microsoft YaHei。Cocos 上若要求字宽一致,应嵌入同一授权字体后验收,不能只复制字体名称。
间距使用 4px 基础单位,常用 8/12/16/24/32px。控件圆角 14px,弹窗 24px,小角标 8px。移动端安全区不得遮住底部操作,常规点击区至少 44×44px;图标本身可以小于点击区。
## 7. 动效、音效与反馈
- 快速连点:棋子运动和转盘动画期间继续接收点击,待执行棋子以紫色描边反馈;按顺序重新判定路线,不重复记录同一棋子。碰撞、重来、换关、进入编辑器或打开弹窗时取消待执行点击。动画仍顺序播放,避免多个运动棋子产生碰撞歧义。
- 按压:150ms,缩放到 94%;不移动命中区域。
- 弹窗:420ms,从上方 60px 和 96% 缩放进入;遮罩约 250ms。
- 星星:分别延迟 300/490/680ms 出现,每枚动画 400ms。
- 离场:总时长随路径长度变化,按实际轨道长度以每单位 60ms 滑行,滑行段限制为 140–800ms,出口收束固定为 180ms。边缘棋子约 320ms 完成离场;从 3 格路线起平滑增加滑行时间,5 格及以上恢复初版总时长(550ms + 每格 85ms,最长 1700ms),新增时间全部用于滑行,出口收束仍为 180ms。不再给短路线添加固定等待。滑行与出口位移使用平滑 S 曲线(smoothstep),起止速度为零,中段流畅加速;缩小同样使用 S 曲线,避免末段突然消失。碎片采用快速展开、缓慢停下的 ease-out 曲线。棋子向外推进约 0.48 个格子半径,缩小后留下短尾迹与 6 枚同色六角碎片;效果结束后再显示结果。不得把消散阶段放在画布外,不引入额外彩虹色。减少动态效果时取消尾迹与碎片,仅保留短路线过渡与成功状态文字。
- 旋转:240ms,快速到位,棋子保持固定。
- 碰撞:总长 650ms,先接近,再接触停顿并让阻挡棋子轻震,最后原路弹回;不改变模型中的位置。
- 音效:首次手势后启动,点击、旋转、离场、碰撞和通关各有短音;设置里可关闭并保存偏好。
- `prefers-reduced-motion` 下取消非必要位移、缩放和震动,仍保留状态文字。
- 手机棋盘禁用 WebKit tap highlight、选中文字和长按菜单,避免整块矩形高亮。
## 8. 验收与变更流程
当前生成的精确对比度见 `design/contrast-report.json`,来自 W3C sRGB 相对亮度公式;校验的是不透明 token 配对。代表结果:主文字/背景约 5.98:1,辅助文字/背景约 4.80:1,白字/主按钮约 6.06:1,轨道/底板约 3.55:1。
透明 PNG、抗锯齿、阴影、真实字体和禁用态仍需在实际画面检查。对比度报告不等于整个游戏已获得 WCAG 合规认证。
每次视觉修改按此顺序:
1. 明确修改哪个语义角色,优先复用现有角色。
2. 修改 `src/design-tokens.js`,运行 `npm run design`。
3. 检查自动生成的 PNG/CSS/JSON 和对比度报告。
4. 运行 `npm test`、`npm run build`。
5. 对五套背景逐一检查场景文字与箭头,并检查离场、旋转和撤销后颜色稳定。检查 390×844 手机布局,以及较矮屏幕;检查主界面、选关、设置、通关/失败和碰撞状态。
6. 验证弹窗不能穿透操作、图标居中、轨道接缝不断裂。
7. 如需替换已接受的图片,明确告知用户素材来源和变化,再更新本表。
Cocos 读取同一 JSON/JS token 和 PNG。`CandyUiSkin` 使用纯色 Sprite、圆角 Mask 和居中的图标;不得在原生侧另外猜颜色。本规范与适配组件已提供,原生场景尚需导入后做视觉验收。