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

LibGDX中程序化生成TiledMap多图层无法渲染问题

LibGDX程序化生成TiledMap多图层渲染异常问题解决

你的代码里有几个关键问题导致多图层渲染异常:

问题分析

  1. 复用同一个图层对象:全程只创建了一个TiledMapTileLayer实例,后续循环反复将其添加到图层列表中。TiledMap的图层列表不会复制对象,添加同一个实例只会让所有"图层"指向同一块数据,最终只会显示最后一次修改的结果。
  2. 坐标变量未重置:第一个生成地板的循环结束后,x和y已走到地图右下角,后续循环继续使用这两个变量设置单元格,会超出地图范围或修改错误位置。
  3. 新图层未初始化:每个程序化生成的图层应该是独立的新图层,而非在地板图层上直接修改。

修正后的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:47:31