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
相关产品推荐
相关产品推荐

