You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tiled地图多单图瓦片集对象层加载成功但无法正常渲染问题排查

Tiled地图对象层无法显示问题排查

问题现象

我在Tiled中创建了包含5个独立瓦片集的地图,其中4个为单张图片的瓦片集对象层,便于后续调整尺寸。目前瓦片图层及其关联瓦片集加载、显示均正常,但所有对象层均无法显示,AssetManager日志显示所有资源已成功加载。

相关文件内容

TMX地图文件(已精简base64编码内容)

<?xml version="1.0" encoding="UTF-8"?>
<map version="1.5" tiledversion="1.7.2" orientation="orthogonal" renderorder="left-up" width="100" height="200" tilewidth="32" tileheight="32" infinite="0" nextlayerid="21" nextobjectid="11">
 <tileset firstgid="1" source="Background.tsx"/>
 <tileset firstgid="2" source="CaveEntrance.tsx"/>
 <tileset firstgid="4" source="CaveEntranceForeground.tsx"/>
 <tileset firstgid="5" source="gather_terrains_3.x.tsx"/>
 <tileset firstgid="7845" source="Fossil.tsx"/>
 <layer id="14" name="Tile Layer 2" width="100" height="200">
  <properties>
   <property name="isForeground" type="bool" value="false"/>
  </properties>
  <data encoding="base64" compression="zlib">
base64compressedstring
  </data>
 </layer>
 <objectgroup id="15" name="Background">
  <properties>
   <property name="isForeground" type="bool" value="false"/>
  </properties>
  <object id="1" name="Background" gid="1" x="0" y="1600" width="3196" height="1604"/>
 </objectgroup>
 <objectgroup id="18" name="CaveForeground">
  <properties>
   <property name="isForeground" type="bool" value="true"/>
  </properties>
  <object id="4" gid="4" x="0" y="1760" width="556" height="439"/>
 </objectgroup>
 <objectgroup id="17" name="CaveBackground">
  <properties>
   <property name="isForeground" type="bool" value="false"/>
  </properties>
  <object id="3" gid="3" x="0" y="1762" width="556" height="439"/>
 </objectgroup>
 <objectgroup id="19" name="Fossil">
  <properties>
   <property name="isForeground" type="bool" value="false"/>
  </properties>
  <object id="5" gid="7845" x="107" y="2339" width="128" height="125"/>
  <object id="6" gid="7845" x="1268" y="2651" width="128" height="125"/>
  <object id="7" gid="7845" x="2290.55" y="3823.61" width="128" height="125"/>
  <object id="8" gid="7845" x="260.242" y="4093.3" width="128" height="125"/>
  <object id="9" gid="7845" x="1669.33" y="5566.03" width="128" height="125"/>
  <object id="10" gid="7845" x="2684.48" y="6275.12" width="128" height="125"/>
 </objectgroup>
</map>

单图瓦片集TSX文件示例

所有同类文件结构基本一致,仅尺寸和关联纹理存在差异:

<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.5" tiledversion="1.7.2" name="CaveEntranceBackground" tilewidth="556" tileheight="439" tilecount="1" columns="0">
 <grid orientation="orthogonal" width="1" height="1"/>
 <tile id="1">
  <image width="556" height="439" source="CaveEntranceBack.png"/>
 </tile>
</tileset>

资源存放规则:tmx地图文件、所有tsx瓦片集文件和位图资源都存放在/assets/maps/同一目录下。

AssetManager加载日志

[AssetManager] Loading: maps/TheVault.tmx, com.badlogic.gdx.maps.tiled.TiledMap
[AssetManager] Loading dependency: maps/game_background.png, com.badlogic.gdx.graphics.Texture
[AssetManager] Loading dependency: maps/CaveEntranceBack.png, com.badlogic.gdx.graphics.Texture
[AssetManager] Loading dependency: maps/CaveEntranceFront.png, com.badlogic.gdx.graphics.Texture
[AssetManager] Loading dependency: maps/gather_terrains_3.a.png, com.badlogic.gdx.graphics.Texture
[AssetManager] Loading dependency: maps/fossil.png, com.badlogic.gdx.graphics.Texture
[diagnostics] maps/gather_terrains_3.a.png, Texture, refs: 1
maps/CaveEntranceBack.png, Texture, refs: 1
maps/CaveEntranceFront.png, Texture, refs: 1
maps/TheVault.tmx, TiledMap, refs: 1, deps: [maps/game_background.png,maps/CaveEntranceBack.png,maps/CaveEntranceFront.png,maps/gather_terrains_3.a.png,maps/fossil.png,]
maps/game_background.png, Texture, refs: 1
maps/fossil.png, Texture, refs: 1
[assetnames] maps/gather_terrains_3.a.png,maps/CaveEntranceBack.png,maps/CaveEntranceFront.png,maps/TheVault.tmx,maps/game_background.png,maps/fossil.png

核心代码

地图加载代码

manager = new AssetManager();
Logger log = new Logger("AssetManager", Application.LOG_DEBUG);
manager.setLogger(log);
manager.setLoader(TiledMap.class, new TmxMapLoader(new InternalFileHandleResolver()));
manager.load("maps/TheVault.tmx", TiledMap.class);

manager.finishLoading();

map = manager.get("maps/TheVault.tmx", TiledMap.class);
Utils.Log("diagnostics", manager.getDiagnostics ());
Utils.Log("assetnames", String.join(",",manager.getAssetNames ()));

地图渲染代码

camera.update();
renderer.setView(camera);
renderer.render();

问题原因与解决方案

核心原因

默认OrthogonalTiledMapRenderer仅支持渲染瓦片图层,不会自动渲染带gid的瓦片对象层,属于libGDX内置渲染器的默认行为,和资源加载状态无关。
另外还有两个容易忽略的衍生问题:

  • Tiled的对象坐标以左下角为基准,libGDX瓦片层默认以左上角为基准,需要做Y轴偏移换算:偏移值 = 地图总高度 * 瓦片高度 - 对象Y坐标 - 对象高度
  • 你当前的单图瓦片集tile id与gid对应关系正确,tsx内tile id从0计数叠加firstgid后和tmx内对象gid匹配,这部分无异常。

修复方案

方案1:手动渲染对象层

在瓦片层渲染完成后,手动遍历所有对象层的gid对象批量绘制:

// 先渲染默认瓦片层
renderer.render();

// 再手动渲染对象层
batch.setProjectionMatrix(camera.combined);
batch.begin();
for (MapLayer layer : map.getLayers()) {
    if (layer instanceof ObjectGroup) {
        for (MapObject obj : layer.getObjects()) {
            if (obj instanceof TiledMapTileMapObject) {
                TiledMapTileMapObject tileObj = (TiledMapTileMapObject) obj;
                TextureRegion region = tileObj.getTile().getTextureRegion();
                // 坐标换算适配libGDX坐标系
                float y = (map.getProperties().get("height", Integer.class) * map.getProperties().get("tileheight", Integer.class)) 
                        - tileObj.getY() - region.getRegionHeight();
                batch.draw(region, tileObj.getX(), y, tileObj.getWidth(), tileObj.getHeight());
            }
        }
    }
}
batch.end();

方案2:自定义渲染器

继承OrthogonalTiledMapRenderer重写render()方法,将对象层渲染逻辑内置,无需每次手动调用。

额外验证点

如果修改后仍无法显示,可先打印日志确认对象层是否被正确加载:

for (MapLayer layer : map.getLayers()) {
    System.out.println("层名:" + layer.getName() + ",类型:" + layer.getClass().getSimpleName());
}

正常输出应包含4个类型为ObjectGroup的对象层,无对应输出则需要检查Tiled导出设置是否正确。


内容的提问来源于stack exchange,提问作者duindain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 03:06:01