主题切换
小游戏 UI/UX 设计基础
预计阅读 30 分钟
版本信息
最后更新:2026-07-09 · 适用基础库:≥ 3.9.0(最低兼容 ≥ 2.30.0)· 微信开发者工具:稳定版 1.06+
前端工程师习惯了响应式 Web 布局和 CSS 媒体查询,但小游戏运行在 Canvas 或引擎渲染层上,没有 DOM 和 CSS。本章讲解小游戏 UI 布局的核心挑战:安全区适配、分辨率策略、触摸热区、字体可读性,以及如何在 Cocos Creator 中实现响应式 UI。
小游戏屏幕适配的特殊性
与 Web 相比,小游戏屏幕适配面临以下差异:
| 维度 | Web 前端 | 小游戏 |
|---|---|---|
| 布局系统 | CSS Flexbox / Grid | 手动计算坐标或引擎 UI 组件 |
| 安全区 | CSS env(safe-area-inset-*) | wx.getSystemInfoSync().safeArea |
| 分辨率 | 视口 + 媒体查询 | 设计分辨率 + 缩放策略 |
| 输入精度 | 鼠标/触控精确 | 手指触控,热区 ≥ 88×88px |
| 字体 | 系统字体 + Web Fonts | 系统字体或位图字体 |
安全区与刘海屏适配
获取安全区信息
typescript
const { safeArea, screenWidth, screenHeight, windowWidth, windowHeight } = wx.getSystemInfoSync()
// safeArea 是避开刘海、圆角、手势条后的可用矩形
const safeTop = safeArea.top
const safeBottom = safeArea.bottom
const safeLeft = safeArea.left
const safeRight = safeArea.right常见适配原则
- 核心 UI 放入安全区:血条、按钮、分数等不要贴在屏幕边缘。
- 背景可延伸至全屏:天空、地面、装饰元素可以超出安全区。
- 底部操作区抬高:iPhone 底部手势条区域(通常 34–44 逻辑像素)避免放按钮。
typescript
class SafeAreaAdapter {
static getSafeInsets() {
const sys = wx.getSystemInfoSync()
return {
top: sys.safeArea.top,
bottom: sys.screenHeight - sys.safeArea.bottom,
left: sys.safeArea.left,
right: sys.screenWidth - sys.safeArea.right,
}
}
}分辨率策略
小游戏没有统一的屏幕比例。常见策略有三种:
1. 固定设计分辨率 + 等比缩放
选择一种主流分辨率(如 750×1334 或 750×1624),运行时按宽度或高度等比缩放。
typescript
const DESIGN_W = 750
const DESIGN_H = 1334
function getScaleFactor(screenW: number, screenH: number) {
// Fit Width:保证宽度完整显示,高度可能裁切或留黑边
return screenW / DESIGN_W
}2. 动态 Canvas 尺寸
在原生 Canvas 项目中,根据屏幕尺寸动态创建画布:
typescript
const canvas = wx.createCanvas()
const ctx = canvas.getContext('2d')
// 保持物理像素清晰
const { windowWidth, windowHeight, pixelRatio } = wx.getSystemInfoSync()
canvas.width = windowWidth * pixelRatio
canvas.height = windowHeight * pixelRatio
ctx.scale(pixelRatio, pixelRatio)3. 引擎内置策略
Cocos Creator 的 Canvas 组件提供:
- Fit Height:高度适配,宽度可能溢出。
- Fit Width:宽度适配,高度可能溢出。
- Show All:完整显示设计分辨率,可能留黑边。
休闲游戏通常选择 Fit Height 或 Fit Width,根据玩法决定以哪条边为基准。
触摸热区与交互设计
手指触控的最小热区
| 元素 | 推荐最小尺寸 | 说明 |
|---|---|---|
| 按钮 | 88×88 px | iOS HIG 推荐 |
| 图标按钮 | 64×64 px | 可配合透明扩展区域 |
| 滑动条 | 高度 ≥ 44 px | 便于精确拖拽 |
| 关闭按钮 | 60×60 px 以上 | 避免误触 |
避免误触的实践经验
- 暂停按钮与广告按钮之间保持 ≥ 20 px 间距。
- 重要操作(如购买、删除)增加二次确认。
- 游戏进行中,虚拟摇杆/按钮应有明显的按下反馈。
字体与可读性
字体选择限制
小游戏无法像 Web 一样自由加载 Google Fonts。可行方案:
- 系统字体:使用
wx.getSystemInfoSync().fontFamilySetting获取用户字体设置,回退到系统默认。 - 位图字体 (Bitmap Font):将美术字预渲染为图片,适合标题和分数。
- 引擎字体:Cocos Creator 支持 TTF 字体导入,但会增加包体。
typescript
// 原生 Canvas 绘制系统字体
ctx.font = 'bold 48px "PingFang SC", "Microsoft YaHei", sans-serif'
ctx.fillStyle = '#ffffff'
ctx.textAlign = 'center'
ctx.fillText('得分 42', screenWidth / 2, 80)可读性原则
- 正文文字 ≥ 24 px(逻辑像素)。
- 标题与背景对比度 ≥ 4.5:1。
- 在复杂背景上加文字描边或半透明底框。
Cocos Creator 响应式 UI 示例
typescript
import { _decorator, Component, Node, view, screen, Widget } from 'cc'
const { ccclass, property } = _decorator
@ccclass('ResponsiveUI')
export class ResponsiveUI extends Component {
@property(Node) topBar: Node | null = null
@property(Node) bottomMenu: Node | null = null
onLoad() {
this.adaptSafeArea()
}
adaptSafeArea() {
const sys = wx.getSystemInfoSync()
const visibleSize = view.getVisibleSize()
const designH = 1334
// 将安全区顶部偏移转换为设计分辨率下的坐标
const topOffset = (sys.safeArea.top / sys.screenHeight) * designH
const bottomOffset = ((sys.screenHeight - sys.safeArea.bottom) / sys.screenHeight) * designH
if (this.topBar) {
this.topBar.setPosition(this.topBar.position.x, designH / 2 - topOffset - 40)
}
if (this.bottomMenu) {
this.bottomMenu.setPosition(this.bottomMenu.position.x, -designH / 2 + bottomOffset + 40)
}
}
}使用 Widget 组件
Cocos Creator 的 Widget 组件可以让节点自动对齐父节点四边或中心。结合代码动态调整 top、bottom 边距,是实现安全区适配的最简单方式。
AI 生成美术概念与 UI 素材
对于没有美术背景的前端开发者,AI 图像生成工具是快速验证视觉风格的高效手段。
典型工作流
用自然语言描述需求 → AI 生成多张概念图 → 人工筛选方向 →
风格锁定(角色表 / Style Reference / LoRA)→ 后处理(去背景 / 调色 / 裁切)→
导入引擎 → 打包图集Prompt 模板
| 用途 | Prompt 示例 |
|---|---|
| 角色概念 | A cute 2D mobile game protagonist, side view, cartoon style, bright colors, clean outline, white background, game asset --ar 1:1 |
| UI 按钮 | A simple game UI button icon, play button, flat design, neon cyan outline on dark background, transparent background, 128x128 --ar 1:1 |
| 背景 | A 2D game background, futuristic neon city at night, parallax ready, dark purple and cyan palette, no text --ar 16:9 |
风格一致性控制
- 固定前缀:把风格描述放在每段 Prompt 开头,保持一致
- 角色表(Character Sheet):一次生成同一角色多角度/多表情
- Style Reference:用参考图锁定整体风格(Midjourney
--sref) - 人工精修:AI 生成图通常需要后处理才能作为最终游戏资源
AI 美术素材的版权与授权
- 免费版 AI 工具通常禁止商用,付费版(如 Midjourney Pro)一般允许
- 避免在 Prompt 中使用知名 IP、商标、角色名
- 保留原始 Prompt、生成参数和人工修改后的源文件,作为版权证据链
- 核心角色/美术建议进行软著或版权登记
Flappy Bird UI 设计实战
以贯穿本教程的 Flappy Bird 为例,对比原生 Canvas 版与 Cocos Creator 版的界面设计。
界面结构
| 界面元素 | 原生 Canvas 版 | Cocos Creator 版 |
|---|---|---|
| 开始界面 | UIManager.drawStartScreen() 绘制标题、按钮文字 | StartPanel 节点,使用 Label + Button 组件 |
| HUD 分数 | drawScore() 用 Canvas 描边文字实现 | ScoreLabel 节点,挂载 Label 组件 |
| Game Over 面板 | drawGameOver() 绘制半透明遮罩 + 文字 | GameOverPanel 节点,默认隐藏,游戏结束时激活 |
| 按钮热区 | 手动计算矩形触摸检测 | Button 组件自动处理,建议 size ≥ 88×88 px |
暗夜霓虹风配色实践
本教程主题色为深色背景 + 青色/粉色霓虹点缀,可直接应用到 Flappy Bird UI:
| 用途 | 颜色值 | 说明 |
|---|---|---|
| 背景 | #0a0a0f | 接近纯黑的深空背景 |
| 主标题 | #00e5ff | 霓虹青色,带发光效果 |
| 强调/按钮 | #ff6ec7 | 霓虹粉色,用于"开始"、"复活"等 CTA |
| 成功/分数 | #00ff88 | 霓虹绿色,分数增长时高亮 |
| 文字描边 | #000000 | 确保在复杂背景上可读 |
Canvas 绘制示例:
typescript
// 霓虹标题绘制
function drawNeonTitle(ctx: CanvasRenderingContext2D, text: string, x: number, y: number) {
ctx.save()
ctx.font = 'bold 64px Orbitron, sans-serif'
ctx.textAlign = 'center'
// 外发光
ctx.shadowColor = '#00e5ff'
ctx.shadowBlur = 20
ctx.fillStyle = '#00e5ff'
ctx.fillText(text, x, y)
// 内部高光
ctx.shadowBlur = 0
ctx.fillStyle = '#ffffff'
ctx.fillText(text, x, y)
ctx.restore()
}关键设计原则
- 保持画面简洁:Flappy Bird 的核心玩法只需要"点击跳跃",开始界面不要堆叠过多按钮。
- 分数 HUD 置顶居中:玩家视线集中在屏幕中央,分数放在顶部中央既醒目又不遮挡管道。
- Game Over 面板明确 CTA:使用粉色霓虹按钮突出"再玩一次",避免用户迷茫。
- 动效克制:小鸟死亡后面板淡入即可,过多特效会分散对失败原因的注意力。
📝 课后练习
练习 1:计算按钮安全位置
题目: 设计一个底部菜单,要求无论是否存在刘海屏,菜单底部始终距离屏幕底部手势条 ≥ 30 px。请写出适配公式。
参考答案:
typescript
const sys = wx.getSystemInfoSync()
const bottomInset = sys.screenHeight - sys.safeArea.bottom
const menuBottomY = -sys.windowHeight / 2 + bottomInset + 30(具体符号取决于引擎坐标系方向。)
本章小结
- 小游戏没有 CSS,安全区、分辨率、热区都需要手动计算或依赖引擎组件。
- 使用
wx.getSystemInfoSync().safeArea获取安全区,核心 UI 必须放在安全区内。 - 分辨率策略选择 Fit Width / Fit Height 要根据玩法和画面构图决定。
- 触摸热区 ≥ 88×88 px,按钮间距和反馈是避免误触的关键。
- 字体优先使用系统字体,标题可用位图字体提升视觉表现。
📚 相关阅读
- Flappy Bird — 原生 Canvas 2D 完整实现 — 手写 UI 绘制逻辑
- Flappy Bird — Cocos Creator 重写 — 引擎 UI 组件化实践
- 小游戏可访问性设计 — 色盲、高对比度、无障碍适配
- 资产管线 — UI 图集与字体资源优化