做2D游戏,关卡编辑器是必需品。
Tiled是老牌方案,功能全,但界面过时、JSON导出格式繁琐、集成要写一堆代码。每次换项目都要重新适配。
LDtk(Level Designer Toolkit)是为现代2D游戏重新设计的关卡编辑器——由《Celeste》主程Maddy Thorson开发,专门针对独立游戏工作流优化。
为什么选LDtk
和Tiled的对比
| 特性 | Tiled | LDtk |
|---|---|---|
| 界面设计 | Qt传统风格 | 现代极简界面 |
| 层级结构 | 图层(Tileset/Layer) | 自定义层级(Levels/Layers) |
| 实体管理 | 对象层(Object Layer) | 专用实体系统 |
| 导出格式 | JSON(通用但冗余) | JSON(精简+类型化)或Tiled格式 |
| Unity集成 | 需要自己写 | 官方插件,一键导入 |
| 自定义属性 | 通用属性 | 强类型字段定义 |
| 价格 | 免费 | 免费开源 |
LDtk的核心优势:关卡结构和游戏逻辑解耦。你定义数据格式,游戏端只接收干净的类型化数据,不需要解析复杂的嵌套结构。
核心概念
Project(项目)
一个LDtk项目(.ldtk文件)包含:
- 层级定义(Levels):每个游戏关卡或场景
- 图块集(Tilesets):瓦片图集
- 实体定义(Entity Definitions):可放置对象的模板
- 自定义字段(Custom Fields):给层级/实体/瓦片附加元数据
Levels(层级)
一个Level对应游戏中的一个关卡或场景。每个Level有独立的尺寸、背景色、引用层。
Project
└── Level: 森林_01
├── Layer: 背景_地面
├── Layer: 前景装饰
├── Layer: 实体层_敌人
└── Layer: 实体层_道具
Layers(层)
LDtk的层比Tiled更灵活。支持多种类型:
| 层类型 | 用途 |
|---|---|
| IntGrid | 整数网格,用于瓦片碰撞数据 |
| Tiles | 图形瓦片,带自动贴图 |
| Entities | 可自定义的实体对象 |
| AutoLayer | 基于IntGrid自动生成的图形层 |
Entity(实体)
实体是LDtk中最强大的概念。你可以定义任意结构的"对象模板":
// LDtk中定义一个Enemy实体
{
"identifier": "Enemy_Slime",
"width": 32,
"height": 32,
"color": "#cc3300",
"fields": [
{ "type": "Float", "name": "health", "default": 3.0 },
{ "type": "String", "name": "aiBehavior", "default": "patrol" },
{ "type": "Enum", "name": "element", "values": ["normal", "fire", "ice"] }
]
}
实体可以放置在关卡的任意坐标,LDtk会导出精确的位置、旋转、缩放数据。
自定义层级结构
LDtk允许完全自定义层级和字段,这是它最强大的地方。
典型2D平台游戏配置
Level: 森林关卡配置
├── IntGrid: collision(碰撞层)
├── Tiles: terrain(地形瓦片)
├── Tiles: decoration(装饰瓦片)
├── AutoLayer: terrain_auto(自动贴图层)
├── Entities: spawn_points(出生点)
├── Entities: enemies(敌人)
├── Entities: items(道具)
└── Entities: triggers(触发器)
每个层级都可以附加自定义字段:
// 关卡层级自定义字段示例
{
"name": "bgmTrack",
"type": "String",
"default": "forest_theme_01"
},
{
"name": "isBossRoom",
"type": "Bool",
"default": false
}
字段类型系统
LDtk支持丰富的字段类型,可以精确描述游戏数据:
| 类型 | 示例值 | 用途 |
|---|---|---|
| Int / Float | 10 / 3.14 |
数值属性 |
| Bool | true/false |
开关类配置 |
| String | "fire" |
文本/枚举键 |
| Enum | `"fire" | "ice" |
| Color | #FF5500 |
颜色配置 |
| Point | {x:10,y:20} |
坐标点 |
| Array | [1,2,3] |
列表数据 |
自动化工作流
AutoLayer自动贴图
AutoLayer是LDtk的杀手级功能——你画好碰撞网格,它自动生成对应的瓦片图形。
IntGrid数值 → AutoLayer规则 → 自动渲染瓦片
例如:
Grid值=1(地面)→ 渲染地面瓦片
Grid值=2(墙)→ 渲染墙瓦片
Grid值=3(草地)→ 渲染草地瓦片
配置规则:
Rule 1: gridValue=1 → tileset[0-3](地面4种变体)
Rule 2: gridValue=2 → tileset[4-7](墙4种变体)
Rule 3: gridValue=1, adjacent=1(top) → 添加草装饰
这样只需要在IntGrid上画碰撞数据,图形自动生成——修改碰撞不需要手动重绘瓦片。
实体预设与随机化
可以给实体设置"出现概率"和"随机变体":
{
"identifier": "Coin",
"randWidth": { "min": 8, "max": 24 },
"randHeight": { "min": 8, "max": 24 },
"fields": {
"value": { "min": 1, "max": 10 }
}
}
LDtk会在导出时自动计算随机范围的精确值,保证每次导出结果一致。
游戏引擎集成
Unity集成(推荐)
Unity有官方LDtk插件:
1. Unity Asset Store搜索 "LDtk" 或 GitHub: deeped/ldtk
2. 安装后:Assets → Import New Level → 选择.ldtk文件
3. 自动生成MonoBehaviour脚本
4. 每个Level和Entity作为组件可直接使用
// 自动生成的Level数据
public class Forest_01 : LdtkLevel
{
public LdtkEntityArray<Enemy_Slime> Enemies;
public LdtkEntityArray<Coin> Items;
public LdtkEntity_SpawnPoint PlayerSpawn;
}
// 加载关卡
var level = FindObjectOfType<Forest_01>();
Instantiate(level.Enemies[0].prefab, level.Enemies[0].center, Quaternion.identity);
Godot集成
# Godot 4.x
func load_level(ldtk_path: String):
var ldtk_file = LDtkReader.new()
ldtk_file.load(ldtk_path)
var level = ldtk_file.get_level("森林_01")
for entity in level.get_entities("Enemy_Slime"):
spawn_enemy(entity.pos, entity.fields)
Defold集成
Defold有社区维护的LDtk第三方库,支持直接导入和实体生成。
最佳实践
实践一:字段驱动设计
在LDtk中定义的字段就是游戏数据的唯一真相来源。
// Enemy实体定义
"fields": [
{ "name": "maxHealth", "type": "Float" },
{ "name": "speed", "type": "Float" },
{ "name": "damage", "type": "Int" },
{ "name": "lootTable", "type": "String" }
]
不要在LDtk里存格式数据,只存游戏逻辑数据——格式问题在游戏端处理。
实践二:关卡模块化
使用Worlds和Layers组织大规模关卡:
World: 第一章
├── Level: 1-1 森林入口
├── Level: 1-2 洞穴
├── Level: 1-3 BOSS房
└── LevelGroup: 森林_共享资源
├── Tileset: 森林地形
└── Tileset: 森林敌人
共享资源层让多个关卡引用同一套美术资产,一处修改全局生效。
实践三:IntGrid作为碰撞数据
不要用Tiles层做碰撞——用IntGrid。
Tiles层存储视觉信息,IntGrid存储逻辑信息。两者分离,修改美术不需要改碰撞数据。
IntGrid值:
0 = 空气(无碰撞)
1 = 地面(可站立)
2 = 平台(可穿过从上方)
3 = 墙体(完全碰撞)
游戏端读取IntGrid值生成物理碰撞体,完全和贴图解耦。
常见问题
Q:LDtk能导出Tiled格式吗?
可以。LDtk支持以Tiled的JSON格式导出,方便已有Tiled集成的项目迁移。
Q:支持瓦片动画吗?
支持。LDtk支持多帧瓦片动画(通过Tileset.animationFrames),游戏端读取帧数据后驱动动画。
Q:可以协作吗?
LDtk的.ldtk文件是单用户格式,多人协作建议用版本控制(Git/LFS)。每个Level也可以单独文件化,方便冲突解决。
下载与资源
官网:https://ldtk.io GitHub:https://github.com/deeped/ldtk itch.io:https://deeped.itch.io/ldtk 支持系统:Windows / macOS / Linux
相关资源
Xmohe Techie:Yarn Spinner对话系统实战指南——对话引擎与LDtk的无缝结合 Xmohe Techie:LibreSprite像素画工具指南——配合LDtk的美术资产制作流程