字体系统设计:Orbitron / Rajdhani / Share Tech Mono 的选择逻辑
> 三种字体,三种信息层级。字体不是装饰,是信息架构。
## 为什么是这三个字体
打开 `src/config/fonts.ts`,你会看到一个极简的字体常量表:
```ts
export const FONTS = {
DISPLAY: 'Orbitron',
BODY: 'Rajdhani',
MONO: '"Share Tech Mono", monospace',
} as const;
```
这三个字体的选择不是随机的,而是按照**信息层级**来分的:
| 字体 | 类别 | 使用场景 | 视觉特征 |
|---|---|---|---|
| Orbitron | Display | 标题、大字 | 几何感强,字母间距大,像飞船仪表盘 |
| Rajdhani | Sans-serif | 正文、标签 | 清晰易读,中等字重,像终端输出 |
| Share Tech Mono | Monospace | 代码、状态信息 | 等宽,像系统日志 |
## Orbitron:标题字体
Orbitron 是 NEON RUNNER 2077 里出现频率最高的字体。`BootScene` 里的标题、`MenuScene` 里的 "NEON RUNNER"、`GameScene` 里的 "COMBAT ARENA // STANDBY"——全都是 Orbitron。
Orbitron 的特点是**几何感**。每个字母几乎都是由直线和直角构成的,没有衬线,没有曲线装饰。这种字体在赛博朋克语境里天然成立——它看起来像"未来"。
在 `index.html` 里,Orbitron 通过 Google Fonts 加载:
```html
<link
href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Rajdhani:wght@400;500;600;700&family=Share+Tech+Mono&display=swap"
rel="stylesheet"
/>
```
注意 `wght@400;700;900`——Orbitron 加载了三个字重。`BootScene` 里用 `56px` 显示标题,`MenuScene` 里用 `88px` 显示主标题,字重的差异让大小变化更明显。
## Rajdhani:正文字体
Rajdhani 是 Rajasthani(拉贾斯坦语)的意思,但它是一个现代无衬线字体。在 NEON RUNNER 2077 里,它主要出现在 `MenuScene` 的按钮标签和 `GameScene` 的占位文字里。
Rajdhani 的特点是**可读性**。在 1280×720 的分辨率下,Orbitron 在小字号下会显得"空"——字母间距太大,信息密度不够。Rajdhani 的字形更紧凑,适合做正文。
## Share Tech Mono:等宽字体
Share Tech Mono 是整个项目里**信息密度最高**的字体。`PreloadScene` 里的加载消息、`MenuScene` 里的版本信息、`GameScene` 里的状态提示——全是等宽字体。
等宽字体的核心价值是**对齐**。在 `PreloadScene` 里:
```ts
const LOAD_MESSAGES = [
'> initializing neon runtime...',
'> loading cyberware modules...',
'> calibrating glitch shaders...',
'> syncing holo interface...',
'> arming neon projectiles...',
'> system ready.',
];
```
这些消息在等宽字体下,每个字符占的宽度相同,`>` 符号会严格对齐。如果用非等宽字体,`>` 和后面的文字会因为字母宽度不同而参差不齐。
## 字体大小系统
`fonts.ts` 里还定义了一套字体大小常量:
```ts
export const FONT_SIZES = {
HERO: 64,
H1: 48,
H2: 32,
H3: 24,
BODY: 18,
SMALL: 14,
TINY: 12,
} as const;
```
这套大小系统不是拍脑袋定的,而是按照**视觉层级**来的:
- `HERO: 64` — `MenuScene` 的 "NEON RUNNER" 标题
- `H1: 48` — `BootScene` 的 "NEON RUNNER 2077"
- `H2: 32` — `GameScene` 的 "COMBAT ARENA // STANDBY"
- `H3: 24` — `MenuScene` 的副标题 "// 2 0 7 7 //"
- `BODY: 18` — 按钮文字、正文
- `SMALL: 14` — 加载消息、状态提示
- `TINY: 12` — 版本号、底部信息
## 字体在 Phaser 和 CSS 中的映射
字体在项目里有两套使用方式:
**Phaser 场景中:**
```ts
// BootScene.ts
this.add.text(x, y, 'NEON RUNNER 2077', {
fontFamily: FONTS.DISPLAY, // 'Orbitron'
fontSize: '56px',
color: '#FCEE0A',
});
```
**CSS 中:**
```ts
// main.css
:root {
--font-display: 'Orbitron', sans-serif;
--font-body: 'Rajdhani', sans-serif;
--font-mono: '"Share Tech Mono", monospace';
}
```
CSS 里的 `font-family` 需要兜底 `sans-serif` 或 `monospace`,因为 Google Fonts 是网络加载的,如果加载失败,浏览器会回退到系统字体。Phaser 里的 `fontFamily` 字符串直接传给 Canvas 2D API,没有兜底机制——所以 `index.html` 里的 `<link>` 必须在 `main.ts` 之前加载。
## 下一章预告
字体系统讲完了,但 NEON RUNNER 2077 的"开机感"真正建立的地方是 `BootScene`。下一章我会拆解这个只有 39 行的场景——为什么它只做一件事,以及为什么"300ms 延迟"是整个游戏体验的起点。
> 字体选择的核心原则:**一个信息层级,一种字体**。不要用同一种字体做所有事,否则信息层级会塌陷。
- 点赞
- 收藏
- 关注作者
评论(0)