LibGDX中程序化生成TiledMap多图层无法渲染问题
LibGDX程序化生成TiledMap多图层渲染异常问题解决
你的代码里有几个关键问题导致多图层渲染异常:
问题分析
- 复用同一个图层对象:全程只创建了一个
TiledMapTileLayer实例,后续循环反复将其添加到图层列表中。TiledMap的图层列表不会复制对象,添加同一个实例只会让所有"图层"指向同一块数据,最终只会显示最后一次修改的结果。 - 坐标变量未重置:第一个生成地板的循环结束后,
x和y已走到地图右下角,后续循环继续使用这两个变量设置单元格,会超出地图范围或修改错误位置。 - 新图层未初始化:每个程序化生成的图层应该是独立的新图层,而非在地板图层上直接修改。
修正后的代码
public class WorldGenerator { // 移除static修饰,避免内存泄漏和多实例冲突 private Texture tiles; private TiledMap map; public TiledMap GenerateWorld(int mapWidth, int mapHeight, int tileWidth, int tileHeight, int exponent, int mapLayers, String noiseType) { int x, y, l; tiles = new Texture(Gdx.files.internal("spriteAtlas.png")); TextureRegion[][] splitTiles = TextureRegion.split(tiles, tileWidth, tileHeight); map = new TiledMap(); MapLayers layers = map.getLayers(); // 生成地板图层 TiledMapTileLayer floorLayer = new TiledMapTileLayer(mapWidth, mapHeight, tileWidth, tileHeight); x = 0; y = 0; for (int i = 0; i < (mapWidth * mapHeight); i++) { Cell cell = new Cell(); cell.setTile(new StaticTiledMapTile(splitTiles[1][0])); floorLayer.setCell(x, y, cell); x++; if (x == mapWidth) { y++; x = 0; } } layers.add(floorLayer); // 生成程序化图层 for (l = 0; l < mapLayers; l++) { // 每个循环创建新的图层实例 TiledMapTileLayer proceduralLayer = new TiledMapTileLayer(mapWidth, mapHeight, tileWidth, tileHeight); double[] noise; switch (noiseType) { case "perlin": noise = NoiseGenerator.normalise(NoiseGenerator.perlinNoise(mapWidth, mapHeight, exponent)); break; case "smooth": noise = NoiseGenerator.normalise(NoiseGenerator.smoothNoise(mapWidth, mapHeight, exponent)); break; case "turbulence": noise = NoiseGenerator.normalise(NoiseGenerator.turbulence(mapWidth, mapHeight, exponent)); break; default: throw new IllegalStateException("Unexpected value: " + noiseType); } // 重置坐标到起始位置 x = 0; y = 0; for (double v : noise) { Cell cell = new Cell(); if (Math.round(v) == 1) { cell.setTile(new StaticTiledMapTile(splitTiles[0][1])); } proceduralLayer.setCell(x, y, cell); x++; if (x == mapWidth) { y++; x = 0; } } layers.add(proceduralLayer); } return map; } }
额外优化提示
- 提前缓存
StaticTiledMapTile实例:不要每次创建单元格都新建StaticTiledMapTile,可以提前把需要的tile实例缓存起来,减少对象创建开销。
更新(2024/04/19):我已放弃尝试通过TiledMap实现该功能,转而采用三维数组方案。
内容的提问来源于stack exchange,提问作者TheDogOfChaos
相关产品推荐
相关产品推荐

