玄学放置 · 像素图标体系
起因
第一版用 emoji 当学科图标(📖 📐 ⚖️ 等等),看起来太"应付"了,跟暗色科技风的整体调子完全不搭。游戏化产品的图标如果没有自己的视觉语言,整个画面就会松散。
决定换成 16×16 的像素艺术。这个尺寸是经过取舍的:太小(8×8)画不下细节,太大(32×32)开发成本指数级上升。16×16 是经典像素风格的"甜区",能塞下足够辨识度的元素,又不会让每个图标的字符画变成一项工程。
渲染方式:SVG 而不是 PNG
放置游戏里图标会出现在多种尺寸场景:侧栏 22px、学科面板 44px、装备槽 30px、人物剪影 120px。如果用 PNG,要么准备多套尺寸切图、要么放大失真,前者维护成本高,后者直接糊掉。
最终选了用 <rect> 渲染像素艺术:
<svg viewBox="0 0 16 16" :width="size" :height="size"
shape-rendering="crispEdges">
<rect v-for="(p, i) in pixels" :key="i"
:x="p.x" :y="p.y" width="1" height="1" :fill="p.color" />
</svg>关键点是 shape-rendering="crispEdges" 这个属性,它告诉浏览器渲染时不要做反锯齿,保证像素块边缘永远锐利。配合 viewBox 始终保持 16×16,在任何尺寸下放大都不会糊。
数据驱动:字符画 + 调色板
图标本体用字符画存储,每张 16 行字符串:
math: {
palette: { 1: '#5eead4', 2: '#0d9488', 3: '#134e4a' },
art: [
'................',
'..1111111111111.',
'..2222222222222.',
'......11....11..',
'......11....11..',
// ...
]
}. 表示透明像素,其他字符通过 palette 映射颜色。这种格式有几个好处:
- 所见即所得:字符画在编辑器里直接能看出大致形状,调整时不用反复跑预览
- 数据短小:每张图 16×16=256 字符 + 一个调色板对象,远小于 PNG
- 可批量处理:用脚本扫描
ICONS字典就能批量做导出、变体、过滤等操作
每个图标 3-5 色独立调色板,避免全局色板膨胀,也方便每个图标走自己的色彩主题。
PixelIcon 组件
parseIcon(name) 把字符画转换成 {x, y, color} 数组,组件渲染时遍历输出 <rect>:
<PixelIcon name="math" :size="32" glow glow-color="#5eead4" />新增了一个 glow 选项:选中态自动加 drop-shadow 外发光,颜色用学科主题色。这是放置游戏画面的常见手法——选中即发光,提示状态变化。
八大学科的视觉语言
每个学科都选了一个最具代表性的元素,并给它一个独有的色板:
| 学科 | 主题元素 | 色板 |
|---|---|---|
| 语言 | 翻开的古籍 + 朱红封边 | 米黄 / 朱红 / 暗红 |
| 数学 | π 符号 | 青亮 / 青深 |
| 政治 | 天平 | 金色系 |
| 历史 | 卷轴 + 文字纹 | 米纸 / 墨字 / 卷边 |
| 地理 | 地球 + 海陆分布 | 海蓝 / 陆绿 / 深边 |
| 物理 | 原子 + 双轨道 + 金核 | 蓝弧 / 金核 |
| 化学 | 锥形烧瓶 + 紫液 + 气泡 | 紫液 / 气泡黄 |
| 生物 | 叶脉 | 浅绿 / 中绿 / 深绿 |
设计时刻意避免直接复制 emoji 的具象表达。比如「政治」用天平而不是 ⚖️ 的具体细节,「化学」用一个简化的锥形瓶轮廓配紫色液体而不是真实试管的复杂结构——16×16 的像素必须舍弃细节、抓住一眼可辨的剪影。
玄学:神秘感的设计
「玄学」作为隐藏学科(项目代号 metaphysics 的彩蛋),需要传达"看不见但存在"的神秘感。我用了三个元素叠加:
- 水晶球:球体由金色辉光(
#fbbf24)外圈包裹亮紫(#ddd6fe)内核 - 全知之眼:球心嵌一只眼,瞳孔用亮金
#fef9c3,营造窥视感 - 紫黑底座:深紫
#1e1b4b与紫光主体形成层次
.......2........
......242.......
.....22422......
....2244422.....
...224111422....
..22411115422...
..24111515142... ← 中央是眼睛
..24115525142...
..24111515142...
..22411115422...
...224111422....
....2244422.....
.....33333......
....3333333.....任务列表也强化彩蛋向:「夜观天象」「抽一张塔罗」「冥想悟道」(最后一个是单次最高收益,呼应"玄学回报最高"的梗)。
集成到业务
替换 emoji 的代价比想象中小:
- <span>{{ subject.icon }}</span>
+ <PixelIcon :name="subject.iconKey" :size="22"
+ :glow="isSelected" :glow-color="subject.color" />mock 数据里 icon: '📐' 改成 iconKey: 'math',业务字段从"图标字面值"变成"图标资源 key"。这一改让后续扩展(变体、动画、特效)有了空间——以后做"罕见装备闪光特效"时,只需要在 PixelIcon 里加一种新的 effect 就行,业务层的 iconKey 不用动。
后续扩展点
像素艺术架构搭完之后,复用面会越来越宽:
- 装备图标(铅笔、橡皮、画笔、校服等)用同一套架构,新加一个 entry 就行
- 人物剪影也可以用 16×16(虽然小,但放大到 120px 已经足够辨识)
- favicon 直接复用「玄学」图标的字符画数据,无需额外作图
- 后续可写一个导出脚本,把所有图标批量产出 SVG 文件作为素材包
这套"字符画 + 调色板 + 单一组件渲染"的小架构,是这个项目里最划算的一次抽象——前期一次投入,后面几乎所有视觉资产都能受益。
总结
像素图标看似只是视觉问题,但在游戏化产品里它会决定整体画面的"专业感"。这次的关键设计:
- 用 SVG 渲染而不是 PNG,解决多尺寸场景的清晰度问题
- 字符画 + 调色板作为底层数据结构,比直接画 SVG 更易编辑
- 业务层只引用 key,把图标实现细节封死在 PixelIcon 内
- 统一架构容纳所有图标类型(学科、装备、道具、人物)
下一篇会聊装备物品系统的搭建,以及一个比较关键的设计转向:把任务从"每个学科同时挂机"改为"全局只能挂机一个"。