引言
关卡是玩家「行走的世界」——而关卡的制作方式直接决定迭代速度与内容上限。本文把 Defold 关卡设计讲透:先讲 Defold 的关卡编辑基础(Tilemap 图块、Collection 组合、碰撞数据),再讲「数据驱动关卡」——用配置/JSON 描述关卡结构(比硬编码快十倍),接着是 Collection 复用与预制关卡(像积木一样拼关),再讲运行时动态构建关卡(程序生成、读表拼关、无限关),然后是玩家自制关卡(UGC)的数据格式与导入导出,最后是关卡编辑器的工程化(版本管理、批量操作、热重载),让你做出「改起来快、内容上限高」的关卡系统。
前置:/defold-editor-asset-pipeline/(编辑器与资源管线)、/defold-script-system-lua/(脚本与工厂)、/defold-physics-collision/(碰撞数据)。游戏设计通用知识见 游戏开发专题。
目录
- 1. 关卡的两条路线:手摆 vs 数据驱动
- 2. Tilemap 关卡编辑:图块图层碰撞
- 3. Collection 复用:关卡积木与预制
- 4. 数据驱动关卡:JSON 描述关卡结构
- 5. 运行时拼关:读表构建世界
- 6. 程序生成关卡:算法与约束
- 7. 玩家自制关卡:UGC 数据格式
- 8. 关卡编辑器工程化
- 9. 常见陷阱
- 10. 速查表
- 延伸阅读
1. 关卡的两条路线:手摆 vs 数据驱动
关卡制作方式决定了迭代速度与内容上限:
路线 A:手摆在编辑器里摆对象(Collection/Tilemap)
+ 直观、所见即所得
- 改动麻烦、难批量、难版本管理
路线 B:数据驱动(JSON/表格描述关卡)
+ 改数据即改关、可批量/程序生成/版本管理
- 不直观,需要「数据 → 世界」的构建器
结论:编辑器手摆做「独特关卡」,数据驱动做「海量/可变关卡」——两者结合
两种路线适用场景:
手摆:主线关卡、叙事关卡、手工打磨的跳台
数据驱动:随机关卡、无尽模式、多关卡变体、UGC 关卡
混合:手摆预制 + 数据配置参数 + 运行时组装
关键权衡:
- 数据驱动关卡的「构建器」要一次写对(关卡质量取决于它)
- 手摆关卡的「可复用性」差(想改全局规则要动每关)
- 好实践:关卡「结构」数据驱动、独特「装饰」手摆
心智:手摆直观、数据驱动可批量——独特关卡手摆、海量关卡数据驱动,结构数据化 + 装饰手摆是现实的混合。
2. Tilemap 关卡编辑:图块图层碰撞
Tilemap(图块地图)是 2D 关卡的地基:
Tilemap 概念:
- 网格(grid):固定的格子尺寸(如 32×32)
- 图块(tile):从图集取一块,放在格子里
- 图层(layer):地形层 / 装饰层 / 碰撞层
- 碰撞数据:每个图块可携带碰撞形状
Defold Tilemap 编辑:
- 在编辑器里用「图块画笔」铺地形
- 图层分离:地面/墙面/装饰分开画
- 碰撞:地形层配碰撞数据(玩家站在上面、墙挡住)
- 图集管理:同一图集多图块 → 高效合批
Tilemap 的碰撞数据:
- 每图块可绑定「碰撞形状」→ 自动生成物理体
- 或手动加 Collision Object 到对应区域
- 常见做法:地形 tilemap + 独立碰撞对象层(更灵活)
- 碰撞与视觉分离:视觉 tilemap + 逻辑碰撞层
Tilemap 的坑:
- 超大 tilemap → 网格数据大 → 用分块(多个小 tilemap)
- 频繁运行时改 tilemap → 性能敏感(改碰撞要重算)
- 半格/坡度 → tilemap 表达复杂,用自由对象拼
心智:Tilemap = 网格 + 图块 + 图层 + 碰撞数据——图层分离视觉与逻辑、地形配碰撞形状,超大关分块,坡度半格用自由对象。
3. Collection 复用:关卡积木与预制
Collection(集合)是 Defold 的「预制件」——复用关卡模块的利器:
Collection = 一组对象 + 组件(是一个「关卡模块」)
例子:一个平台模块、一个敌人区、一个解密房间
复用方式:
- 同一 collection 多处实例化(工厂)
- collection 内嵌 collection(模块嵌套)
- 参数化实例化(不同参数 → 不同变体)
-- 运行时实例化一个「关卡模块」
local room = factory.create("main/rooms/puzzle_room", pos, nil, {index = 3})
用 Collection 拼关:
- 模块化:平台、陷阱、敌人区各自是 collection
- 组合:关卡 = 一组 collection 实例(手工摆或数据驱动)
- 复用:同一模块反复用 → 内容翻倍不翻工作量
- 变体:collection 参数化(难度/颜色/数量)→ 同模块多形态
Collection 的工程价值:
- 批量编辑:改一个 collection = 所有实例生效
- 版本管理:模块独立更新,关卡结构稳定
- 团队协作:不同人负责不同模块
心智:Collection 是「关卡积木」——模块化、参数化、可嵌套,改一个模块所有实例更新,让关卡像搭积木一样组合。
4. 数据驱动关卡:JSON 描述关卡结构
把关卡描述成数据——从「手摆」升级到「改数据即改关」:
// level_03.json(示意)
{
"name": "level_03",
"size": {"w": 20, "h": 12},
"tiles": [
"XXXXXXXXXX",
"X........X",
"X..P.....X", // P = 出生点
"X...##....X", // # = 砖块
"X....E....X" // E = 敌人
],
"enemies": [
{"type": "walker", "x": 4, "y": 3, "speed": 1.5}
],
"props": [
{"type": "coin", "x": 6, "y": 5}
]
}
字符画(ASCII)作为关卡蓝图:
- 每行一个字符串 → 直观(人一眼能看懂关卡形状)
- 每个字符映射一种元素(P 玩家、E 敌人、# 砖、. 空地)
- 编辑器里用字符画拼关,代码读字符映射成对象
- 优点:可读、可版本管理、可程序生成
数据驱动的完整管线:
-- 读关卡 JSON → 构建世界
local level = load_json("levels/level_03.json")
-- 字符画 → 图块/对象
for y, row in ipairs(level.tiles) do
for x, ch in row:gmatch(".") do
local elem = ELEMENT_MAP[ch] -- 字符 → 元素
if elem then build_element(elem, x, y) end
end
end
-- 对象(敌人/道具)→ 实例化
for _, e in ipairs(level.enemies) do
spawn_enemy(e.type, e.x, e.y)
end
心智:数据驱动关卡 = JSON/字符画描述 + 构建器读表实例化——字符画让关卡「可读可版本管理」,构建器一次写对就是内容工厂。
5. 运行时拼关:读表构建世界
「读表拼关」把数据驱动落地成运行时行为——三种拼法:
① 静态读表:加载时一次构建(固定关卡)
② 动态分段:边玩边加载关卡片段(无尽模式/超长关)
③ 程序拼接:多关卡模块按规则组合(关卡转场、房间生成)
运行时构建的核心代码:
-- 动态分段:按玩家进度加载「下一段」
function load_segment(self, seg_id)
local seg = get_segment_data(seg_id) -- 数据源(JSON/打包表)
local offset = self.segment_end
for _, elem in ipairs(seg.elements) do
spawn_at(elem.type, offset.x + elem.x, offset.y + elem.y)
end
self.segment_end = self.segment_end + seg.width
end
资源管理:
- 预加载 vs 按需加载:远段落按需加载、进段落预加载
- 已通过的段落 → 卸载(释放内存)
- 分段之间的「衔接点」要校验(高度差/平台对齐)
**分段拼接的规则**:
- 相邻段的「入口/出口」要对齐
- 难度曲线:越往后越难(配置权重)
- 主题/天气随机变化
心智:运行时拼关 = 读表构建 + 按需加载/卸载 + 衔接点校验——动态分段让关卡无限长,难度曲线靠配置权重。
6. 程序生成关卡:算法与约束
程序生成(Procedural Generation)用算法造关——关键是「约束」:
程序生成 = 随机 + 约束
随机:变化性(每次不同)
约束:可玩性(保证通关可能、难度合理)
经典算法:
① 随机地形(Perlin/噪声):
用噪声生成高度/密度 → 地形自然起伏
② 房间 + 走廊:
随机放置房间 → 走廊连接 → 保证连通(BFS 校验)
③ 约束模板填充:
预设「模板块」(平台、坑、敌区)→ 按规则摆放
→ 约束最容易控制(难度/节奏可控)
④ 回溯/生成-验证:
生成 → 用「可玩性检测」(能否通关)验证 → 不行重来
-- 生成-验证示例
function generate_level(self, seed)
while true do
local level = generate(seed)
if is_playable(level) then -- 校验:通关可能、无死局
return level
end
seed = seed + 1 -- 换个种子重来
end
end
程序生成的工程要点:
- 种子可控:同一种子 → 同关卡(可复现、可测试)
- 难度保证:首关简单、逐关变难
- 资源上限:生成物别超内存/对象上限
- 视觉约束:保证可读性(不生成视觉混乱)
心智:程序生成 = 随机 + 约束——房间走廊保证连通、模板填充控制难度、生成-验证兜底可玩性;种子可控,保证每关都「能玩、有变化」。
7. 玩家自制关卡:UGC 数据格式
UGC(玩家自制关卡)让内容产出翻倍——核心是「数据格式 + 导入导出」:
UGC 关卡格式要求:
- 可导出:玩家编辑 → 导出为可分享数据
- 可导入:下载他人关卡 → 解析 → 构建
- 可校验:关卡数据要过「合法性检查」(防作弊/防崩溃)
UGC 格式设计:
// 分享的关卡格式(简化)
{
"format": "plume_level",
"version": 1,
"name": "我的跳跳关",
"author": "player123",
"tiles": ["XX.P.X", "X...EX"],
"settings": {"time_limit": 60, "par": 3}
}
导入校验清单:
- 格式/版本匹配
- 图块在合法集合内(防「奇怪字符」破坏)
- 尺寸在合理范围(防超大关卡卡死)
- 出生点存在且可达
- 资源引用合法(贴图/音效存在)
UGC 的工程化:
- 关卡编辑 UI:触屏摆放图块 → 导出
- 分享/下载:云端存储 + 关卡码(短码/二维码)
- 社区版块:榜单、点赞(驱动 UGC 生态)
- 安全:关卡数据不可执行(纯数据,防脚本注入)
心智:UGC = 可导出可导入可校验的数据格式——导入必过合法性检查(防破坏/防卡死/防注入),关卡码分享 + 榜单驱动生态,内容产出翻倍。
8. 关卡编辑器工程化
关卡编辑器的「工程化」让多关卡生产高效:
版本管理:
- 关卡数据(JSON/字符画)进 git → 可 diff/可回溯
- 二进制场景文件难 diff → 优先文本数据驱动
批量操作:
- 批量改全局参数(难度系数、主题)→ 数据层统一改
- 关卡列表集中管理(index.json 登记全部关卡)
热重载:
- 改关卡数据 → 运行时重载(调试快)
- Defold 热重载 + 数据重载 → 边改边看
-- 关卡目录(登记所有关卡)
local LEVEL_INDEX = {
{id = "level_01", data = "levels/level_01.json", next = "level_02"},
{id = "level_02", data = "levels/level_02.json", next = "level_03"},
}
生产流水线:
设计(字符画/编辑器)→ 数据(JSON)→ 构建器(运行时)
→ 测试(通关校验/自动跑关)→ 发布(打包进资源)
关卡测试的自动化:
- 自动跑关:模拟输入跑一遍 → 验证能通关(回归)
- 参数校验:关卡 JSON 过 Schema(字段齐全/值合法)
- 性能预算:关卡对象数/粒子数在预算内
心智:关卡工程化 = 数据进 git + 批量参数 + 热重载 + 自动跑关——文本数据驱动是版本管理的钥匙,自动化跑关是质量底线。
9. 常见陷阱
| 陷阱 | 现象 | 规避 |
|---|---|---|
| 硬编码关卡 | 改一关改代码 | 数据驱动 + 构建器 |
| 超大 tilemap | 加载慢/卡顿 | 分块 + 按需加载 |
| 碰撞与视觉分离 | 看得见走不过去 | 碰撞层统一校验 |
| 程序生成无约束 | 生成不可玩关卡 | 生成-验证 + 连通校验 |
| UGC 不校验 | 恶意关卡卡死 | 导入合法性检查 |
| 二进制场景 | 难 diff/回溯 | 文本数据进 git |
| 无自动跑关 | 改关引入回归 | 自动通关回归 |
10. 速查表
全篇速查:
| 主题 | 结论 |
|---|---|
| 路线 | 手摆独特关、数据驱动海量关 |
| Tilemap | 网格+图层+碰撞,分块防卡 |
| Collection | 关卡积木,模块化复用 |
| 数据驱动 | JSON/字符画 + 构建器 |
| 拼关 | 读表 + 按需加载 + 衔接校验 |
| 程序生成 | 随机 + 约束 + 生成-验证 |
| UGC | 可导出可导入可校验 |
| 工程化 | 数据进 git + 批量参数 + 热重载 |
| 测试 | Schema 校验 + 自动跑关 |
| 混合 | 结构数据化 + 装饰手摆 |
一句话记忆:关卡制作 = 手摆(独特)与数据驱动(海量)的结合——Tilemap 用网格图层碰撞、分块防卡,Collection 是关卡积木模块化复用;数据驱动用 JSON/字符画描述关卡、构建器读表实例化,动态分段按需加载、衔接点校验,程序生成用「随机 + 约束 + 生成-验证」保证可玩;UGC 关卡可导出可导入可校验、导入必过合法性检查;工程上数据进 git、批量参数、热重载、自动跑关回归——改数据即改关,内容上限不再受「手摆速度」限制。
延伸阅读
- /defold-editor-asset-pipeline/ — 编辑器、图集与资源管线
- /defold-script-system-lua/ — 工厂、消息与实例化
- /defold-physics-collision/ — 碰撞数据与关卡物理
- /defold-hot-reload-updates/ — 热重载与资源管理
- 游戏开发专题 — 关卡设计与游戏机制
- 杂项专题 — 数据格式与序列化(UGC 关卡格式)
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。