LibGDX - Load a TiledMap tileset from a big TextureRegion

1.1k views Asked by At

I'm currently developing a game using LibGDX and I have come to the following situation:

  1. The game uses TiledMap maps for each level in it. I created a large tile set and packed it to a ~1300x1300 PNG file (non-POT). Tiles are 128x128 + gutter.
  2. The scene is rendered using an OrthogonalTiledMapRenderer. Actually it is a slight modification of the built-in OrthogonalTiledMapRenderer, which does not set the camera projection to the SpriteBatch renderer, causing an extra flush each loop:

    private class OrthogonalTiledMapRenderer2 extends OrthogonalTiledMapRenderer {
        public OrthogonalTiledMapRenderer2 (TiledMap map, float unitScale, Batch batch) {
            super(map, unitScale, batch);
        }
    
        @Override
        public void setView (OrthographicCamera camera) {
            //batch.setProjectionMatrix(camera.combined); //This causes an unneeded flush in my case: the projection matrix is already set.
            float width = camera.viewportWidth * camera.zoom;
            float height = camera.viewportHeight * camera.zoom;
            viewBounds.set(camera.position.x - width / 2, camera.position.y - height / 2, width, height);
        }
    }
    
  3. I draw several other objects (enemies, items, active elements) before I start rendering the tiledMap. This has to be this way since there are not tiles on all the cells of the map, and I want these objects to hide under some tiles. All this objects share the same camera projection, so I start the SpriteBatch when I want to render these objects, and leave it open when I start the map renderer. All these objects are currently packed into a texture about 1000x1000 in size, but it is comprised of lots of small objects so they can be wrapped around the tileset's region (read below). So the thing goes:

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        for (Thing t : things) {
            t.draw(batch);
        }
        orthogonalTiledMapRenderer2.setView(camera);
        orthogonalTiledMapRenderer2.render(tileLayer); //Uses the same batch
        //...
         batch.end();
     }
    

Now, the thing is clear: My plan is to pack everything into a single Power-Of-Two texture (to the affordable size of 2048x2048), both the TiledMap tile set and the objects sheet, so I use a single texture and I can minimize batch flushes to the GPU. The problem is I can't find a way of loading a TiledMap using an external SpriteRegion, not even using the AtlasTmxTiledMapLoader.

Can anyone point me in the right direction? Is there a way to load a TiledMap passing a TextureRegion as the tileset, instead of creating a new, unreachable Texture, and having to flush once for the map and again for the rest of your sprites?

1

There are 1 answers

3
Phil Anderson On

I haven't done this, but you ought to be able to pass your single Power-Of-Two texture atlas into using the map-level property 'atlas' as long as the regions are named apropiately.

From the Javadoc...

public class AtlasTmxMapLoader extends BaseTmxMapLoader

A TiledMap Loader which loads tiles from a TextureAtlas instead of separate images. It requires a map-level property called 'atlas' with its value being the relative path to the TextureAtlas. The atlas must have in it indexed regions named after the tilesets used in the map. The indexes shall be local to the tileset (not the global id). Strip whitespace and rotation should not be used when creating the atlas.