做2D游戏的人,大概率都经历过那个“用记事本画地图”的阶段:在代码里敲一个二维数组,0代表空地,1代表砖块,2代表尖刺,美术每给一张新切片图,就照着像素把数字一个一个填进去。地图少的时候还能硬扛,等关卡数量上来,改一个格子的查错时间能把人折磨疯。我第一次正式使用Tiled,就是因为一个横版项目的场景文件乱到完全没法维护——几千行的CSV,每个数字背后的图块全靠人脑记忆,最后我俩被迫停下来,花两天时间把Tiled引入工作流。之后新关卡的制作时间直接缩到原来的三分之一。这篇文就以我实际项目里的使用经历为主线,把从安装、建图、图层规划、自动图块到引擎对接的完整链路走一遍,重点讲说明书上不写、但做真实项目时一定会碰到的东西。
Tiled是什么?一句话:开源免费的2D地图编辑器。它的核心能力是把“网格化的地图数据”变成可视化编辑,再导出成JSON、TMX这些通用格式,交给Unity、Godot、Phaser、Cocos Creator等引擎去加载。只要你做的游戏是2D、场景能拆成格子——横版卷轴、俯视角RPG、六边形战棋——它基本都能用上。下文有给新手的完整操作,也有专门写给已经上手的开发者的进阶建议。
1. 为什么我不再自己写地图编辑器
1.1 关卡数据不该锁死在代码里
早年间做项目,图都是美术画一整张,然后我拿切片工具切成小块,在代码里手动维护ID对照表。这种做法的致命问题有三个。第一,地图和代码强耦合,每次调整布局都要改代码、重新编译,策划想微调一个平台位置,得等程序动手;第二,ID容易记混,同样是草地,边缘的、带花的、压扁的,各有各的编号,人脑不是数据库;第三,不可视化,拼出来的效果要跑起来才能看,拼错了只能在屏幕里一格一格地找。
Tiled解决的正是这三件事:地图以独立文件存在,关卡设计师只管刷格子,不碰代码;图块以缩略图方式平铺在面板里,所见即所得;图层和自定义属性把“这块砖能不能走”“这个点是什么出生点”这类信息变成编辑器里的可视化标签。这就是所谓的数据与画面分离——地图是纯数据,引擎只负责读取渲染,编辑器只是生产工具,两个东西彻底解耦。
1.2 什么时候真的不需要Tiled
虽说是常规武器,但也有反例。程序化生成的地牢、无尽跑酷的随机拼接、纯运行时动态生成的关卡,这些场景本身没有“人工设计”的过程,代码里写个算法直接生成反而更稳。我在另一个小项目里就试过用代码生成房间连通图,再手动拼屋内的装饰——结果发现装饰部分还是要人眼把关,最后还是把“屋内布置”这一层交回给了Tiled。结论是:凡是需要人参与的关卡设计环节,Tiled都值得用;凡是纯算法的内容生成,别硬套编辑器。
顺带说,Tiled完全免费、开源、跨平台,Windows、macOS、Linux都有安装包,社区资源也厚,搜索任何“某某引擎+Tiled”都有大量现成经验,单是这一点已经把自研编辑器的门槛抬得很高了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从新建工程到画完第一张地图
2.1 新建地图时,这四个参数不能拍脑袋
打开Tiled,第一步是“New Map”对话框。很多人急着点确定,把参数随便一填,结果后面返工。关键参数有四个:方向(正交、斜45度、交错六边形等)、地图宽高(以格为单位)、格子尺寸(像素)、是否无限地图。
方向选择取决于游戏视角。横版游戏用正交;俯视角RPG如果美术是轴测图,选等轴(isometric);六边形战棋选六边形。格子尺寸必须跟着美术的切片走——美术出的是16x16的像素风,就别设成32;如果底稿是96px一格的高清风,宁可让格子变大也别硬缩。很多项目死在“美术按原尺寸出图,程序按预想尺寸切”,两边没对齐。
地图宽高的计算方式很简单:关卡预期像素总长除以格子尺寸。假设一个横版关卡的游玩区域是3840像素宽,32px的格子,那就是120格。我通常会多留10%的余量,并加上可扩展的方向预留。无限地图选项留给需要超大世界或动态扩张的场景,但它有个隐藏代价:画好的内容如果后期要导给某些引擎,部分工具对无限地图的兼容性一般,这点在后面避坑清单里还会展开。
2.2 导入图块集:切片图细节决定成败
地图建好先别急着画,把图块集导入。操作路径是“Map > New Tileset”,选择图集图片,然后填三个值:Tile Width、Tile Height、Spacing。前两个好理解,Spacing(间距)和Margin(边距)是新手最容易忽略的——如果美术在整张图集里给每个小图块周围留了1px的透明出血线,这里就必须填1,否则Tiled会把出血线也当成图块内容,画面边缘就会出现一圈诡异杂色。
图块命名的规范也建议一开始就定好。我习惯按“主题_位置_变体”的格式命名,比如“grass_mid_01”“wall_top_03”,因为后面对接引擎或写自动刷图脚本时,能直接按名字筛选图块,省掉大量按ID猜谜的时间。
2.3 画笔工具的使用顺序:先大面积后细节
Tiled自带一套完善的笔刷:印章笔刷(快捷键B)用来单格绘制,油漆桶(F)用来填充连续区域,矩形选择+填充适合铺大块地面,橡皮擦(E)清理错误,魔术棒(M)可以按颜色选区。我的实际操作顺序是:先用油漆桶或矩形选择把整张地形的大色块铺好,再用印章笔刷补齐边缘和细节,最后用选择工具框选微调。这样最快,而且不容易出现“刷着刷着格子边缘对不上”的问题。
对了,图层记得提前建好。刚开始用Tiled的人容易把所有东西画在一个图层里,后期想单独调装饰层或碰撞层时完全没有余地。强烈建议在建工程时就把基准图层结构搭好:底图层、交互/碰撞层、装饰层、光照层,留个空模板备用,每个新关卡直接另存副本。
3. 三种图层各司其职,别把所有东西都堆进Tile Layer
3.1 Tile Layer:按渲染顺序从下往上排
Tiled的图块层(Tile Layer)是基于网格的,适合放场景里的静态贴图内容。图层在面板里的顺序就是渲染顺序,底部的先画、顶部的后画。横版项目我通常会开四五层:最下面一层放远景和基岩,第二层放地面砖块,第三层放可站立的平台,第四层放前景装饰(草、花、碎石),必要时最上面加一层半透明遮罩来增强纵深感。
一个常被忽略的点:图块层的数量会影响文件体积和引擎加载时间。别为了一点点细节无限加层,能用一张图块解决的装饰,就不要拆成三个层。我见过有人把每个小装饰都单独开层,结果导出的JSON有几十MB,加载直接卡顿。宁可把同类的装饰拼在一张大图块集里,用多格来表现。
3.2 Object Layer:碰撞、出生点和触发器的最佳归宿
对象层(Object Layer)是Tiled相对被低估的功能。它不绑定网格,可以放置任意坐标的矩形、椭圆、点、多边形、折线等形状,并且每个对象都能挂自定义属性。这意味着:玩家的出生点、敌人的巡逻路径、事件触发器、门的ID、宝箱的掉落表,这些“非地图贴图”的信息,全部可以用对象层管理。
我强烈建议把碰撞检测放在对象层,而不是写在Tile Layer里。原因有两个:一是矩形和多边形碰撞能精确贴合任意地形,包括斜坡和空心平台;二是策划可以直接在编辑器里拖拽调整碰撞框,不需要程序重新编译。具体做法是单独建一个名为“collision”的对象层,把静态障碍物画成矩形,斜坡用多边形贴合,然后用引擎读取时统一处理。
3.3 Image Layer与自定义属性:把信息写进地图
图像层(Image Layer)适合放两种情况:一是场景远处的整幅背景图,不需要切图块;二是做个关卡草图参考,摆在半透明图层上,等底图完成后删掉。它不是最常用的层,但能解决“大背景怎么切才不浪费”的问题。
真正让Tiled强大的,是它可以在地图、图层、图块、对象四个层级上挂自定义属性。比如在某个图块上写“walkable=false”,在某个对象上写“type=spawn_point”“team=red”。这些属性会原样进入导出的数据,引擎读起来非常方便。建议团队里列一张属性命名规范表,所有人共用一套键名,不然就会出现在代码里同时存在“Walkable”“walkable”“canWalk”三种写法的惨剧。
4. 自动图块是效率倍增器,但要讲究用武之地
4.1 地形笔刷的原理:边缘和转角的排列组合
手工一格一格地刷草地和泥土过渡带,既慢又容易漏。Tiled的地形笔刷(Terrain Brush)就是为这个设计的。它的原理是:你定义一种“地形类型”,再把图块集里所有过渡状态的图块(通常是一套3x3组合,共数十张)按边缘、转角、内部等状态一一指定给笔刷。之后你拿笔刷一划,Tiled会自动根据周围格子匹配正确的那块过渡图。
这套机制最适合自然地形过渡:草地混泥土、沙漠混岩石、水面混沙滩。我在一个俯视角项目里用地形笔刷刷了整张256x256的地图,过渡处几乎无人工痕迹,比手刷快了差不多十倍。
4.2 Wang Tiles:多材质交接的正确打开方式
比地形笔刷更精密的是一套叫Wang Tiles的机制,它也内置于Tiled中。简单理解,地形笔刷管理的是“一种地形与另一种地形的过渡”,而Wang Tiles把过渡关系拆成边和角的组合,可以同时处理多种材质的两两交接,甚至三四种材质汇在一起的角落。如果你的场景里同时有草地、泥土、沙地、水岸,并且它们两两之间都有过渡需求,用地形笔刷会累死,用Wang Tiles则是半个下午搞定的事。
配置入口在Tileset编辑器里,把图块按“边/角”的规则归类到Wang集合中。曲线可能稍微陡一点,但成果是长期复用的,一次配好,所有关卡都能用。
4.3 自动图块不是万能的,我的取舍建议
用了两年自动图块,我的经验是:自然材质过渡优先用自动,建筑结构尽量手刷。原因很简单——自动过渡的逻辑是“四周自动判断”,但建筑里的门框、柱子、墙檐讲究的是精确位置和美术意图,自动匹配往往会给出意料之外的组合。手刷看似慢,但建筑的规律性强,复用率高,一个模板墙就能刷一片,实际效率并不低。
还有一个细节:随机笔刷(Random Mode)很适合做植被散落——选好几个草、石头、小花的图块,开随机模式在地图上涂抹,瞬间就能铺出一片自然感的草坪,比手动一个个摆省太多事。但我建议把这些随机装饰单独放一层,如果以后想整体调整或删除,不用重构底图。
5. 导出与引擎对接:这一步决定项目能不能跑起来
5.1 导出格式选型:TMX、JSON、Lua怎么选
Tiled支持多种保存格式。最常用的是TMX(XML格式)和JSON。我的选择逻辑是:如果引擎生态里已经有成熟的Tiled插件(Unity、Godot、Phaser都是),直接看插件推荐格式;如果准备自己写解析器,JSON比XML更容易处理。Lua格式在LÖVE等Lua引擎里用得多,但大部分2D引擎社区首选还是JSON或TMX。
这里是关键决定:图块集是“嵌入到地图文件里”还是“存成独立的TSX文件”。嵌入的好处是单文件分发简单,坏处是同一份图集在每张地图里都复制一份,文件体积和合并冲突都会变大。独立TSX文件的推荐场景是大型多人协作项目——图集只维护一份,地图文件只引用路径,改图集一次,所有地图跟着生效。团队版本管理时,TSX合并通常也比整份地图文件更可控。
5.2 Unity接入:Tiled2Unity与SuperTiled2Unity
Unity没有原生TMX支持,社区里知名度最高的两个工具是Tiled2Unity和SuperTiled2Unity。Tiled2Unity历史更久,但作者已经停止维护,对新版Unity和Tiled较新格式支持有限;SuperTiled2Unity是它的现代替代品,持续维护,能处理对象层、多边形碰撞、自定义属性,还能生成对应的Prefab和碰撞组件。
接入的大致流程:给Unity装好插件,把Tiled导出的文件放进工程,插件自动生成Prefab。这里有个坑:插件对Tiled版本有要求,升级Tiled后导出的文件格式可能变化,导致插件不识别。稳妥做法是锁定团队内部的Tiled版本,并提前测试导出再升级。
5.3 Godot直读TMX:流程最短的方案
Godot对Tiled支持比较友好,历史版本里能直接导入TMX并生成TileMap。Godot 4之后用TileMapLayer节点承载地图数据,配合自定义脚本解析TMX同样可行。最灵活的路线是写一个轻量脚本在运行时加载TMX:读图块ID映射到TileSet源,读对象层生成碰撞体和节点。工作量不大,但胜在完全掌控。
我提醒一句:Godot的TileSet源和Tiled图块集的ID映射需要注意顺序一致性。如果Tiled里图块顺序调整过,而Godot侧的TileSet还是旧的,渲染就会错位。解决的办法是每次修改Tiled图集后重新生成Godot TileSet,或者写一个批处理脚本自动同步。
5.4 坐标与锚点:对接时最容易翻车的地方
对接时翻车最多的地方不是格式,是坐标。Tiled的原点在左上角,Y轴向下,这恰好和多数2D游戏引擎的世界坐标一致。但对象层的坐标语义需要注意:一个矩形对象记录的是左上角顶点的位置,而不是中心;多边形对象则是逐顶点坐标。在引擎里生成Prefab时,若预制体锚点在中心,就得把Tiled的坐标加上宽高的一半才算准。等轴地图更麻烦,Tiled的等轴坐标是把菱形网格摊平成矩形存储的,引擎侧要么也按矩形读取,要么手动做坐标转换,这个一定在接入前想清楚。
另外,Tiled支持图块动画(帧序列图块),导出的JSON里会自动带animation字段。引擎解析时直接按帧切换即可,省去自己写序列帧逻辑。但不同引擎对动画播放速度的单位定义不同(毫秒/秒),接的时候注意换算。
6. 两年Tiled工作流沉淀出的避坑清单
6.1 图块ID的顺序雷区
图块集里每一格都有固定ID,引擎靠ID找到对应贴图。一旦地图画到一半,你去图块集里插了一个新图块或调换了顺序,会导致所有已保存地图的ID整体偏移,画面集体错乱。这个坑我踩过不止一次,修复办法只有重新映射ID。经验:图块集尽量一次性规划完整,后期要加新图块时,放在末尾追加,不要插在中间。
6.2 外部TSX、版本管理与协作规范
前面说过嵌入还是外部TSX的选择。补充一点版本管理细节:TMX和TSX都是文本格式,放入Git后是可读的,但每次保存的差异行数可能很大。如果团队多人同时编辑同一张地图,冲突几乎是注定的。缓解办法是细分地图文件——每人负责一个区域文件,或者用文件锁约定当前由谁编辑。另外给所有图块、对象、层的命名建一份规范文档,贴在项目wiki里,防止各写各的。
6.3 无限地图的偏移陷阱
无限地图模式下,你的地图实际上是从一个可移动的原点向外扩张的。导出数据时,Tiled会记录一个“无穷地图的起点偏移”,如果引擎插件不处理这个偏移,贴图的网格位置就会整体错位。我遇到过一张看似正常的地图,导出后在游戏里整体左右错了几十格,排查半天才发现是无限地图原点没对齐。如果项目对地图尺寸要求不苛刻,建议直接用固定尺寸地图,省心。
6.4 碰撞命名的统一规范
Tiled的碰撞处理常见的两派做法:一是给图块挂“walkable=false”这类属性;二是单独建对象层画碰撞框。两派我都用过。单图块属性的好处是零额外绘制量,坏处是只能覆盖矩形碰撞,遇到斜坡、空心平台就无能为力;对象层的优势是精确但也意味着每张图都要手动补充一遍碰撞框。我的建议:静态矩形障碍用图块属性,特殊地形用对象层,两种方案并行,并在属性命名上强制统一(比如一律叫“solid”,不用“block”“collidable”的混写)。
6.5 模板地图与经验沉淀
几年下来我发现最容易提升团队效率的,不是某个技巧,而是一张“模板地图”。它包含已经搭好的图层结构、统一命名的对象层、预置的摄像机边界和出生点、常用属性预设。每次新关卡,把这个模板另存再开画,能省掉至少小半天的时间。配合Tiled的“Object Template”(对象模板)功能,把敌人、宝箱、门这些常用物件做成模板,拖动即可复用。
如果让我回到刚接触Tiled的时候,我一定会对当时的自己说一句:别急着开画,先花半天规划图层、属性和对象模板,后面省下来的时间是按天计的。这也是我在多个项目里反复验证过的结论。
