文本与字体
《渡口夜话》带妆彩排那天,台口裱好的字幕框一直空着——九宫格的画框是第 15 章的手艺,词儿却还在编剧秋白的手稿上。这天他把稿子拍在桌上:“第二幕的词都齐了。上字幕。”
这一章把文字搬进 2D 世界。文字看起来是个简单需求——“在屏幕上写一行字”——但游戏里的文字活在渲染管线里:字体是资产,字形要光栅化成纹理,排版要处理换行与对齐,伤害飘字还得会动、会淡出。一路拆开:
- 第一行字与满屏豆腐——
Text2d三分钟上手,然后亲眼看中文变成一排豆腐块:默认字体只认 95 个 ASCII 字符,而且这事一声不吭; - 字模也是资产——字体文件用
AssetServer加载,TextFont指定用哪副字模、刻多大字号;顺带交代本书的中文字体从哪来、为什么要子集化; - 字号的真相——
font_size是“按多大字号刻字模”,Transform缩放是“把照片放大”;行高LineHeight与磨边FontSmoothing两个旋钮; - 把词排进框——
TextBounds给文字画地界,LineBreak定换行规矩,Justify管行与行的对齐,与Anchor各司其职; - 提词器——运行时改
Text2d字符串,排版自动跟上:一个打字机效果; - 富文本——
TextSpan把一块文本拆成多段,各管各的字体、颜色、下划线、删除线、底色,外加整块的影子Text2dShadow; - 台上的字与玻璃上的字——同一套样式组件在 UI 里的镜像
Text,第 28 章的预告; - 夜战——综合战:阿燕劈木人桩,每一击触发 Event(第 8 章),Observer 当场铸出会上飘、会淡出的伤害数字,连击牌用
Text2dWriter实时改字。
这些类型住在 bevy_text(排版引擎与样式组件)和 bevy_sprite(Text2d 本体)里,用的时候照旧从 bevy::prelude 来,少数几个(TextBounds、LineHeight、FontSmoothing 等)要从 bevy::text 显式引入。
配套 crate 是 code/ch16-text。assets/fonts/ 里有两个中文字体文件——它们是 Noto Sans SC 的子集(GB2312 字符集,每个约 1.9 MB),由 scripts/make_ch16_assets.py 下载原始字体、裁剪并按 OFL 许可证的要求改名生成,仓库里已经备好,许可证全文见同目录的 OFL.txt。木人桩和阿燕的练剑帧沿用第 15 章的调色板,也出自同一个脚本。为什么字体要这么折腾,下一节撞了墙你就明白了。