跳转到内容

瓦片地图

瓦片地图系统加载 Tiled 地图(.tmj / .json),渲染瓦片图层,支持自动相机裁剪、逐图层着色/透明度、视差滚动和碰撞生成。

编辑器瓦片地图创建

你可以完全在编辑器内创建和绘制瓦片地图,无需任何外部工具。

创建瓦片地图

  1. Hierarchy 面板中右键 → 创建Tilemap
  2. 在创建对话框中设置瓦片大小,选择 有限无限 地图模式
  3. Tilemap 组件 Inspector 中分配 tileset 图片

瓦片调色板

选中瓦片地图实体时,瓦片调色板 面板会自动打开。它提供 5 种工具:

工具快捷键说明
画笔B绘制单个瓦片或印章多瓦片区域
矩形R拖拽填充矩形区域
油漆桶G洪水填充相同类型的相邻瓦片
橡皮擦E擦除瓦片(任何工具下右键也可擦除)
吸管I从地图中采样瓦片作为当前画笔

印章选择:在调色板网格中拖拽选择多瓦片区域,然后使用画笔工具印章绘制整个选区。

翻转:使用工具栏按钮在绘制前水平或垂直翻转瓦片。

无限地图

无限地图使用稀疏块存储——只有绘制过的区域占用内存。渲染器使用 16×16 瓦片块,具有以下特性:

  • 脏标记:只有瓦片发生变化的块才在每帧重建顶点
  • 块级裁剪:屏幕外的块完全跳过
  • 动画瓦片追踪:不包含动画瓦片的块跳过重建检查

图层管理

通过瓦片调色板中的图层下拉菜单添加、删除、重命名和重新排序图层。每个图层拥有独立的瓦片数据和可见性开关。

快速开始

最简单的使用方式是通过编辑器:

  1. 从 Tiled 导出地图为 JSON(.tmj
  2. .tmj 文件和 tileset 图片放在项目资源文件夹中
  3. 为实体添加 Tilemap 组件,将 Source 设置为 .tmj 文件

场景加载器会自动解析地图、通过 AssetServer 加载 tileset 纹理,并注册到渲染管线。

组件

Tilemap

标记组件,引用 Tiled 地图源文件。场景加载器读取此字段,在场景实例化前预加载地图数据和 tileset 纹理。

属性类型默认值说明
sourcestring''.tmj / .json 地图文件路径

TilemapLayer

描述单个瓦片图层的渲染数据。Tiled 地图中每个可见图层会创建一个带有此组件的实体。

属性类型默认值说明
widthnumber10图层宽度(瓦片数)
heightnumber10图层高度(瓦片数)
tileWidthnumber32瓦片宽度(像素)
tileHeightnumber32瓦片高度(像素)
texturenumber0Tileset 纹理句柄
tilesetColumnsnumber1Tileset 图片中的列数
layernumber0排序图层索引
tilesnumber[][]瓦片 ID 平铺数组(行优先)
tintColor{r:1,g:1,b:1,a:1}逐图层着色
opacitynumber1图层透明度(0–1)
visiblebooleantrue是否渲染该图层
parallaxFactorVec2{x:1,y:1}视差滚动因子

工作原理

场景加载管线

当场景包含带有 Tilemap 组件的实体时,场景加载器会:

  1. 读取 source 字段(如 maps/level1.tmj
  2. 通过 AssetServer 加载 JSON 并使用 parseTmjJson 解析
  3. 解析 tileset 图片的相对路径
  4. 通过 AssetServer.loadTexture() 加载 tileset 纹理并注册其尺寸
  5. 使用 registerTilemapSource() 缓存解析后的地图数据

运行时,TilemapPlugin 读取缓存,每帧提交可见图层进行渲染。

构建目标

瓦片地图资源管线适用于所有构建目标:

  • 编辑器预览:通过预览 HTTP 服务器的 AssetServer 加载
  • 微信小游戏 / 可玩广告:通过 RuntimeAssetProvider 使用打包资源加载
  • Web 构建:与编辑器预览相同,资源从构建输出提供

代码加载

在场景加载器之外需要从代码加载瓦片地图时,使用底层 API:

import { parseTmjJson, loadTiledMap, registerTextureDimensions } from 'esengine';
// 解析 Tiled JSON 数据
const mapData = parseTmjJson(jsonObject);
// 通过 AssetServer 加载 tileset 纹理
const textureHandles = new Map<string, number>();
for (const tileset of mapData.tilesets) {
const info = await assetServer.loadTexture(tileset.image);
textureHandles.set(tileset.image, info.handle);
registerTextureDimensions(info.handle, info.width, info.height);
}
// 将瓦片地图图层实体生成到世界中
const entities = loadTiledMap(world, mapData, textureHandles);

C++ 解析器(WASM)

对于包含外部 tileset(.tsj 文件)的地图,使用 parseTiledMap,它委托给 C++ 解析器:

import { parseTiledMap } from 'esengine';
const mapData = await parseTiledMap(jsonString, async (source) => {
// 解析外部 tileset 文件
return await assetServer.loadText(source);
});

loadTiledMap 选项

选项类型默认值说明
generateObjectCollisionbooleantrue从 Tiled 对象图层创建碰撞体
collisionTileIdsnumber[]自动检测应生成碰撞体的瓦片 ID

碰撞生成

对象图层碰撞

Tiled 对象图层自动转换为物理刚体。支持的形状:

  • 矩形BoxCollider,半尺寸与原始尺寸匹配
  • 椭圆CircleCollider,以较大轴为半径
  • 多边形 / 折线BoxCollider,拟合包围盒
  • → 跳过

每个碰撞对象创建一个静态 RigidBody 实体和相应的碰撞体。

瓦片碰撞

在 Tiled 中为 tileset 中的瓦片添加自定义属性 collision = true 来标记可碰撞瓦片。加载器读取这些 ID 并生成合并后的碰撞矩形:

const entities = loadTiledMap(world, mapData, textureHandles, {
collisionTileIds: [1, 2, 3],
});

碰撞合并

相邻的碰撞瓦片自动合并为更大的矩形,减少物理刚体数量。算法逐行扫描,尽可能向右和向下扩展每个矩形:

合并前: [1][1][1] 合并后: [ 1 ]
[1][1][1] [ 1 ]

这产生更少、更大的 BoxCollider 刚体,提升物理性能。

TilemapAPI

底层运行时瓦片操作 API:

方法说明
TilemapAPI.initLayer(entity, w, h, tw, th)为实体初始化瓦片图层
TilemapAPI.destroyLayer(entity)销毁瓦片图层
TilemapAPI.setTile(entity, x, y, tileId)设置单个瓦片
TilemapAPI.getTile(entity, x, y)获取瓦片 ID
TilemapAPI.fillRect(entity, x, y, w, h, tileId)用指定瓦片填充矩形区域
TilemapAPI.setTiles(entity, tiles)Uint16Array 设置所有瓦片
TilemapAPI.hasLayer(entity)检查实体是否有已初始化的图层

编辑器工作流

你可以通过两种方式创建瓦片地图:

方式 A — 在编辑器中原生绘制(推荐新项目使用):

  1. 在 Hierarchy 中右键 → 创建Tilemap(参见上方编辑器瓦片地图创建
  2. 使用 瓦片调色板 直接在 Scene View 中绘制、擦除和管理图层

方式 B — 从 Tiled 导入

  1. 在 Hierarchy 中为实体添加 Tilemap 组件
  2. 使用资源选择器将 Source 字段设置为 .tmj.json Tiled 地图文件
  3. 编辑器自动加载地图、解析 tileset 纹理并渲染图层
  4. 碰撞对象显示为 Gizmo 叠加层

图层属性

Tiled 图层属性直接映射到 TilemapLayer 字段:

Tiled 属性TilemapLayer 字段说明
opacityopacity图层透明度
tintcolortint十六进制颜色字符串(#AARRGGBB#RRGGBB
parallaxxparallaxFactor.x水平视差因子
parallaxyparallaxFactor.y垂直视差因子
visiblevisible图层可见性

下一步

  • 物理 — 碰撞组件和事件
  • 精灵 — 与瓦片地图一起使用精灵渲染
  • 渲染概览 — 相机、变换、渲染顺序