下载 App

如何让嗒啦啦实现 160+ 文本角色的实时字体编辑系统?

04/10221 浏览开发交流
作者:浠涫的攻略姬-
## 为什么需要字体系统?
在游戏开发中,字体的选择和使用是一个看似简单却非常重要的问题。很多开发者可能会问:不就是用默认字体吗?为什么还要搞那么复杂的字体系统?
让我结合《节拍前夜》的实际开发经历,来聊聊这个话题。
### 问题背景
说起来都是泪,我们一开始也觉得"不就是用默认字体吗?"
最初项目用的是 TapTap Maker 引擎内置的 **MiSans**:- ✅ 技术上很完美:支持中英文混排、自带 Emoji Fallback 机制- ❌ 视觉上一言难尽:配上蓝底白字,活脱脱一个"雷霆 UI"
TapTap
后来我们换成了阿里巴巴普惠体,但依然有这些痛点:
1. **视觉表现力不足**:标题、正文、数字用同样的字体,缺乏层次感2. **与游戏主题不符**:音乐节奏游戏用一个普普通通的字体,缺少音乐感3. **调整字体麻烦**:设计师觉得某个文本字体不合适,要程序员改代码、重新编译4. **无法快速迭代**:不同屏幕、不同文本角色的字体需要反复试错,效率很低
### 解决方案
我们最终决定做一套完整的字体系统:
1. **8 个字体族覆盖游戏场景**:正文、标题、趣味、叙事、正式等不同需求2. **160+ 文本角色统一管理**:每个按钮、标题、标签都有自己的字体角色3. **游戏内实时编辑器**:设计师在游戏运行中就能改字体,立即看到效果4. **云端同步保存**:修改后自动保存,多设备同步
## 选定的 8 个字体族
我们从 29 个备选字体(加嗒啦啦搜索)中精选了 8 个(可以让嗒啦啦构建一个界面给你预览),覆盖游戏常见的排版需求:
| 字族名 | 字体文件 | 中文名 | 用途 | 大小 ||--------|---------|--------|------|------|| **sans** | AlibabaPuHuiTi-Regular.ttf | 阿里巴巴普惠体 | 通用正文 | 838K || **heiti** | SourceHanSansSC-Regular.ttf | 思源黑体 | 强调正文 | 1.9MB || **display** | SmileySans-Oblique.ttf | 得意黑 | 展示/标题 | 2.6MB || **impact** | YouSheBiaoTiHei.ttf | 优设标题黑 | 冲击力标题 | 1.4MB || **fun** | ZhanKuKuaiLeTi.ttf | 站酷快乐体 | 趣味文本 | 5.4MB || **wenkai** | LXGWWenKai-Regular.ttf | 霞鹜文楷 | 文学/叙事 | 19MB || **serif** | SourceHanSerifSC-Regular.otf | 思源宋体 | 正式文本 | 12MB || **fangsong** | ZhuqueFangsong-Regular.ttf | 朱雀仿宋 | 仿宋文本 | 8.5MB |
### 为什么选这 8 个?
**实战经验分享**(虽然我们字体系统还不够完美,但这些选择逻辑是通用的):
1. **正文用普惠体**:免费、开源、易读,覆盖 90% 的通用文本场景2. **标题用得意黑**:斜体设计,有音乐感,适合音乐游戏3. **数字用标题黑**:粗体、醒目,Combo、伤害数字一眼就能看见4. **叙事用文楷**:文学感强,战斗日志、事件文本看起来像小说5. **趣味用快乐体**:活泼可爱,偶尔用在奖励、彩蛋等场景6. **正式用宋体/仿宋**:图鉴、说明等需要严肃感的地方
## 怎么在 TapTap Maker 中注册字体?
作为萌新开发者,你不需要自己手动下载字体文件,直接让嗒啦啦(AI)帮你搞定!
### 第一步:让嗒啦啦帮你下载字体
在对话框里直接说:
```嗒啦啦,帮我下载以下字体到项目的 assets/Fonts/ 文件夹:(嗒啦啦帮我搜索有什么字体可以用)1. 阿里巴巴普惠体 (AlibabaPuHuiTi-Regular.ttf)2. 思源黑体 (SourceHanSansSC-Regular.ttf)3. 得意黑 (SmileySans-Oblique.ttf)4. 优设标题黑 (YouSheBiaoTiHei.ttf)5. 站酷快乐体 (ZhanKuKuaiLeTi.ttf)6. 霞鹜文楷 (LXGWWenKai-Regular.ttf)7. 思源宋体 (SourceHanSerifSC-Regular.otf)8. 朱雀仿宋 (ZhuqueFangsong-Regular.ttf)```
### 第二步:让嗒啦啦帮你修改 main.lua
然后说:
```嗒啦啦,帮我在 main.lua 中注册这 8 个字体族,添加到 UI.Init 的 fonts 配置里```
嗒啦啦会自动帮你生成类似这样的代码:
```luaUI.Init({    fonts = {        { family = "sans", weights = {            normal = "Fonts/AlibabaPuHuiTi-Regular.ttf",        } },        { family = "heiti", weights = {            normal = "Fonts/SourceHanSansSC-Regular.ttf",        } },        { family = "display", weights = {            normal = "Fonts/SmileySans-Oblique.ttf",        } },        { family = "impact", weights = {            normal = "Fonts/YouSheBiaoTiHei.ttf",        } },        { family = "fun", weights = {            normal = "Fonts/ZhanKuKuaiLeTi.ttf",        } },        { family = "wenkai", weights = {            normal = "Fonts/LXGWWenKai-Regular.ttf",        } },        { family = "serif", weights = {            normal = "Fonts/SourceHanSerifSC-Regular.otf",        } },        { family = "fangsong", weights = {            normal = "Fonts/ZhuqueFangsong-Regular.ttf",        } },    },    designSize = 1080,})```
### 第三步:让嗒啦啦帮你创建 FontStyleConfig 模块
接着说:
```嗒啦啦,帮我创建一个 FontStyleConfig 模块,用于管理游戏中的文本角色字体配置```
嗒啦啦会帮你创建完整的 FontStyleConfig.lua 文件,包含:- 文本角色注册机制- 智能字体获取- 变更通知系统- 联动机制
### 第四步:让嗒啦啦帮你接入编辑器
最后说:
```嗒啦啦,帮我在 MaterialEditOverlay 中添加字体编辑 Tab,支持实时预览和云端保存```
这样一套完整的字体系统就搞定了!
#
TapTap
# 基础用法:如何使用字体
注册好字体后,用起来非常简单:
```lua-- UI.Label 用 fontFamily 属性local label = UI.Label({    text = "玩家名称",    fontFamily = "wenkai",  -- 用文楷    fontSize = 16,    fontColor = { 255, 255, 255, 255 }})
-- UI.Button 也一样local button = UI.Button({    text = "开始游戏",    fontFamily = "impact",  -- 用标题黑    fontSize = 24,    onClick = function() end})
-- NanoVG 直接绘制用 nvgFontFacelocal nvg = UI.GetNVGContext()nvgFontFace(nvg, "impact")  -- 用标题黑nvgFontSize(nvg, 32)nvgText(nvg, 100, 100, "PERFECT!")```
## 为什么需要 FontStyleConfig 模块?
基础用法虽然简单,但实际开发中会遇到几个问题:
1. **硬编码太麻烦**:160+ 个文本角色,每个都要写 fontFamily,改起来疯了2. **没有统一管理**:不知道哪些文本用了哪些字体,容易混乱3. **不能实时预览**:改字体要改代码、重新编译,效率很低4. **多设备不同步**:一台设备调好的字体,另一台设备还要重调
FontStyleConfig 模块就是为了解决这些问题而设计的。
## FontStyleConfig 核心功能
### 1. 文本角色管理
把游戏中的所有文本都注册为角色:
```lua-- 批量注册文本角色FontStyleConfig.RegisterBatch({    ["battle.player_name"] = { "sans", 16 },    ["battle.enemy_name"] = { "sans", 16 },    ["battle.hp"] = { "sans", 14 },    ["battle.judgment"] = { "impact", 28 },    ["battle.damage"] = { "impact", 24 },    ["battle.log"] = { "wenkai", 14 },    ["battle.log_headline"] = { "display", 20 },    -- ... 更多文本角色})```
### 2. 智能联动系统
同类文本自动同步:
```lua-- 所有按钮字体联动FontStyleConfig.LinkFontFamily({    "battle.skill_btn",    "bpause.btn",    "bpause.btn_pri",    -- ... 更多按钮})
-- 字号比例联动FontStyleConfig.LinkFontSize("reward.card_name", {    "reward.card_name",  -- 基准    "reward.card_tier",  -- 自动按比例计算    "reward.card_desc",  -- 自动按比例计算})```
### 3. 实时编辑器
在游戏内实时调整字体:- 按屏幕分类管理文本角色- 实时预览效果- 一键重置功能- 云端同步保存
### 4. 保存机制
字体编辑器的修改会自动保存到云端,但如果需要持久化到代码中,可以这样做:
1. **查看修改日志**:在游戏中调整完字体后,查看控制台日志,会显示所有修改的文本角色
2. **让嗒啦啦修改代码**:复制日志内容,然后对嗒啦啦说:
```嗒啦啦,帮我把这些字体修改持久化到代码中:[复制日志内容]```
嗒啦啦会帮你:- 更新 FontStyleConfig 的默认值- 修改相关文件中的字体配置- 确保修改被永久保存
这样即使清除云端数据,字体配置也会保持不变。
## 实战应用:快速上手指南
### 1. 创建带绑定的文本组件
```lua-- 创建自动绑定的标签local label = FontStyleConfig.Label("battle.player_name", {    text = "玩家名称",    fontColor = { 255, 255, 255, 255 }})
-- 创建自动绑定的按钮local button = FontStyleConfig.Button("battle.skill_btn", {    text = "技艺",    onClick = function() end})```
### 2. 监听字体变更
```lua-- 注册监听器local listenerId = FontStyleConfig.Listen(    { "battle.damage", "battle.judgment" },    function(roleKey, style)        -- 处理特殊逻辑,如重新计算布局        if roleKey == "battle.damage" then            RecalculateDamageTextPosition()        end    end)
-- 清理监听器(重要,防止内存泄漏)FontStyleConfig.Unlisten(listenerId)```
### 3. 批量重置
```lua-- 重置整个屏幕的字体设置FontStyleConfig.ResetScreenOverrides("Battle")```
## 我们的不足与改进空间
虽然这套系统解决了很多问题,但我们也有很多做得不够好的地方:
### 1. 没有多字重支持
**问题**:8 个字体族全部只注册了 normal 字重,粗体靠字号+2 模拟
**教训**:设计时要考虑字重需求,粗体在标题、强调等场景很常用
### 2. 没有字体 fallback 链
**问题**:中文字体之间没有 fallback 机制,生僻字可能显示方块
**教训**:如果游戏有大量生僻字(比如古风游戏),要考虑 fallback
### 3. 74MB 字体资源没有子集化
**问题**:8 个中文字体 + Twemoji 共约 74MB,对于独立游戏来说体积不小
**教训**:中文字体最好做子集化(只保留游戏用到的字)
### 4. UI 层和 NanoVG 层字体双轨注册
**问题**:UI.Init 注册一次,NanoVG 的 nvgCreateFont 又注册一次
**教训**:设计时尽量统一一套注册机制
## 最佳实践建议
### 1. 合理规划文本角色
按 `screen.element` 命名,保持一致性:- `battle.player_name`、`battle.enemy_name`- `shop.item_name`、`shop.item_price`- `reward.card_name`、`reward.card_tier`
### 2. 利用联动系统
将相关文本角色分组,减少维护成本:- 所有按钮字体联动- 所有卡片文本字号比例联动- 同类屏幕的标题字体联动
### 3. 设置合理默认值
为每个文本角色设置合适的默认字体和字号:- 正文:sans,14-16px- 标题:display,20-28px- 数字:impact,18-24px- 叙事:wenkai,14-16px
### 4. 清理监听器
切屏时及时清理监听器,防止内存泄漏:- ScreenManager 在切屏时调用 `ClearAllBindings()`- 自管理屏幕手动 `Unlisten()`
### 5. 测试不同设备
确保字体在不同分辨率下显示正常:- 手机端(DPR=2-3)- 平板端(DPR=1.5-2)- 桌面端(DPR=1) 结语
《节拍前夜》的字体风格编辑系统展示了如何在游戏中实现一套完整的实时字体配置方案。通过 FontStyleConfig 的设计,我们不仅解决了实际开发中的字体管理问题,还为设计师提供了直观、高效的编辑工具。
这套系统的核心价值在于:- **提升开发效率**:实时预览,无需重新编译- **保持视觉一致性**:联动系统确保同类文本风格统一- **简化维护**:集中管理所有文本角色的字体配置
虽然在排版深度和性能优化方面还有提升空间,但作为游戏内工具,它已经很好地满足了开发需求。希望这个方案能为其他开发者提供参考,让字体调整不再成为开发中的痛点!
---
**技术栈**:UrhoX、Lua、DataOverride 系统**适用场景**:游戏内字体管理、实时样式调整**开发难度**:中等
猜你想搜
taptap 制造fontstyleconfig模块
别再烧积分了!从每次 2000 到每次 50 的血泪经验截图
别再烧积分了!从每次 2000 到每次 50 的血泪经验
适用场景:所有在用 TapTap Code 开发游戏的小白 难度:★☆☆☆☆ 背景最近群里总有人"炫耀"一次操作花了几千积分,说实话这不是值得高兴的事——这是在告诉所有人你的开发方式有根本性问题。我也走过这条弯路,所以来说说怎么改。 积分消耗的本质是什么积分 = AI 处理的 token 数量 = 你发给 AI 的内容 + AI 回给你的内容所以烧积分的本质只有两种: 你让 AI 做了大量无效/重
精华
81 赞
23 回复
如何提升你游戏中的UI美术水平截图
如何提升你游戏中的UI美术水平
一、请为你的游戏挑选一款合适的字体 很多开发者没有注意到其实UI界面中最重要的元素是字体,一款合适的字体能给整个游戏的界面感官带来蜕变。 请看案例 那么如何挑选适合自己的字体呢? 我总结出了一些小经验可供参考: 黑体:通用 宋体:古风、武侠、修仙 楷体:古风、武侠、修仙 圆体:卡通、动漫、Q版 科技:科幻、未来、电子 顺手分享一个免费可商用字体网站: 当然 如果你不知道自己的游戏适合什么风格
精华
126 赞
44 回复
永恒虚空持续开发日记1——关于游戏中的新名词:场频截图
永恒虚空持续开发日记1——关于游戏中的新名词:场频
写在前边:首先感谢TapTap制造版主大大@汪崽 对于作品潜力的肯定,给与了我积分计划二的权限[表情_不好意思]。这边也在加紧开发改进各种功能中,期望尽快给大家带来成熟的版本。[表情_猫咪举手] 大家好,我是永恒虚空的制作人黑猫不详,大家叫我黑猫就好。从今天开始我将以后置开发日记的形式给大家分享我在TapTap制造中制作的游戏永恒虚空的开发过程,新人希望大家多多关照! 今天先给大家介绍我作品中最重
投票
3 赞
01:29
官方阅,申请积分计划2,希望官方继续支持我完成这款游戏,截图
官方阅,申请积分计划2,希望官方继续支持我完成这款游戏,
视频内容只是一部分, 本游戏耗时3个月,目前完成进度百分之80, 是生存游戏,进入修仙界,走剧情找到宗门加入, 这时游戏才是真正开始, 提升实力境界后就可以变强,获取功法法术法宝, @视频内是游戏里挑战妖族入侵一种主流玩法,游戏就是围绕着这个来进行, 还有很多地方可以战斗,获得资源修炼变强,比如去藏书阁学习功法, 去法宝楼抽法宝,每一个宗门数十个法宝抽取 去修仙界探索,获得各自的资源,可能遇见妖兽
1 赞
3 回复
2D 等轴测视角:完整理论截图
2D 等轴测视角:完整理论
2D 等轴测视角:完整理论 一、视角的本质 什么是等轴测 人站在高处斜着往下看地面,地面上的方格子不再是正方形,而变成了菱形。这就是等轴测的视觉本质。 俯视(正上方看下去): 等轴测(斜上方看下去): ┌──┬──┬──┐ ◇ ├──┼──┼──┤ ◇ ◇ ├──┼──┼──┤ ◇ ◇ ◇ └──┴──┴──┘ ◇ ◇ ◇ 正方形网格经过旋转 + 压缩,变成了菱形网格。 为什么是 2:1
6 赞
【Tap make 塔拉拉之立项干货】萌新看过来!截图
【Tap make 塔拉拉之立项干货】萌新看过来!
题外话:本人也是tap make 使用者之一。塔啦啦忠实信徒、天哥忠实拥护者、八年游戏策划经验的低级策划。但是!我已经做出来一款5000+热度、且稳定可更新的框架、并且还在持续产出更多游戏内容的橘猫! 这几天正好在开新坑。我是3月初加入的tapmake大家庭。两周时间于3月25日将这个作品上架。当时的全凭感觉摸索。如今,自己也是一个有自己项目的小菜鸡了。今天,就来分享一下,如何高效的制作一款高大上
投票精华
69 赞
24 回复
浅记《阿方的旅程》开发历程截图
浅记《阿方的旅程》开发历程
预计阅读时长10分钟,欢迎您先品鉴游戏,再回来看这篇“流水账” 这是我第一次实际接触“用自然语言制作游戏”,也是我第一次接触游戏开发工作,所以一切都是从零开始,跌跌撞撞,懵懵懂懂。[表情_豹哭] 我是通过获得的本次开发资格,6月22日晚,在微信公众号收到了测试资格的消息,最开始公布主题“跳跃”的时候,脑子里最先想到的就是几款非常经典的游戏「马里奥」「Flappy Bird」「Doodle Jump
10 赞
1 回复
【UI教程】如何将已有的效果图应用为实际的UI界面截图
【UI教程】如何将已有的效果图应用为实际的UI界面
在经过了一些折腾和比较折磨的尝试后,我总算是摸清楚了嗒啦啦怎么把UI效果图转换为实际游戏中的UI组件,今天就给大家带来这部分的经验分享。 tips:1.本篇教程需要各位掌握最基本的ps使用,具体的操作部分我会大致讲解,但仍需各位自行学习ps的基本操作,部分可以由ai代劳的环节我会注明。 2.本篇教程需要在以我前两篇教程作为前置环节,请在阅读这两篇前置教程后再进行本篇教程内容的学习 在按照前
12 赞
5 回复
塔拉拉20万分经验分享截图
塔拉拉20万分经验分享
前言 不是教程也不是官方,只是分享一下自己开发过程中遇到的问题和经验。 自上个月拿到资格后,便废寝忘食开始了塔拉拉的无代码做游戏探索,一开始想做一个简单的游戏先试试效果,然后就开始了一个本来是小游戏却消耗近20w分的项目,先说说这其中遇到的问题和积分消耗大户。 一、开始开发 本地新建文件夹,写好你这个游戏的策划案,主文件介绍核心玩法(重中之重)、美术风格,然后分文件介绍游戏中的各种功能/系统,做好
77 赞
19 回复
01:26
《霓虹幸存者》是一款霓虹科幻风格的轻量幸存者小游戏截图
《霓虹幸存者》是一款霓虹科幻风格的轻量幸存者小游戏
玩家将操控宇宙飞船,在不断逼近的敌潮中移动、闪避与战斗。击败敌人可以获得能量并升级武器,逐步形成导弹轰炸、激光穿透、浮游炮护航等不同战斗流派。 随着时间推进,敌人会以更密集的波次来袭,Boss 也会逐步登场。你需要在越来越危险的战场中不断强化火力,清空敌潮,尽可能生存到最后。 说两句题外话。我本来是一名菜鸡godot开发者,目前疯狂遇到瓶颈,项目重构了2次了。已经彻底丧失信心!但这次通过tapta
3 赞
2 回复