Don
Don

Reputation: 987

Libgdx: how to draw a rounded border around a TiledMap with dynamic dimensions?

In libgdx I have a TiledMap that I fill with different Cells:

cell.setTile(new StaticTiledMapTile(reg1));
cell.setTile(new StaticTiledMapTile(reg2));
cell.setTile(new StaticTiledMapTile(reg...));

where reg is a texture region.

I render with:

render = new OrthogonalTiledMapRenderer(map);
render.setView(cam);
render.render();

Throughout the game, the number of columns, number of rows and size of the cells will vary, so they must remain dynamic.

Now, around this TiledMap, I want to add a rounded border. Below I am showing some examples in png of how I am planning to do it : from left to right, first is a top border, then a top-right corner, then a right border. Each of these png files has square dimensions.

top border top-right corner right border

What I want to achieve below, here is a zoom to the top right corner of the TiledMap:

enter image description here

I am planning to use these pngs as TextureRegions that I can set as cells in my TiledMap, something like that:

    for (int x = 0; x < numcol+2; x++) {
            for (int y = 0; y < numrow+2; y++) {
                Cell cell = new Cell();                 

                if (y==numrow+1) {
                    cell.setTile(new StaticTiledMapTile(b_mid_top));
                }

                if (y==0) {
                    cell.setTile(new StaticTiledMapTile(b_mid_bottom));
                }
etc.

I am having multiple issues with the dimension of the pngs: as I mentioned, the size of the cells may vary throughout the game. To my knowledge there is no way to resize a cell or a textureregion from a png as I would need. So I could use Image, resize them dynamically, add them as actors to a stage and draw the stage, but I fear I might loose the benefit of using a TiledMap. Also, I would have to deal with stage coordinates on the one hand and TiledMap coordinates on the other and it doesn't sound the best approach.

So I am a bit lost! What is the best approach to draw my border around my TiledMap? I am ready to abandon any of my current ideas for a better one. I am not very experienced with Libgdx so sorry if I have done some silly mistake.

Upvotes: 0

Views: 884

Answers (1)

bemeyer
bemeyer

Reputation: 6231

I think the idea is good. In case the tilesize changes the bordersize changes too. You can't create a different sized tile as frame around it. In case you want to create always the same frame, you can use a simple Ninepatch with the size of the Map.

create something like this:

NinePatch p = new NinePatch(texture, 5, 5, 5, 5); // the edge sizes are 5px here.

Inside of the render method you draw it at the size of the tilemap. you can optain the sizes from the Map object:

p.draw(batch, 0, 0, tilesize*tilecountx, tilesize*tilecounty);

If you do not liket his idea you can go for the second version. Create a new TiledMap with the boarder as tiles you need to copy the whole Tilemap with an offset of 1 tile (since you need to have 1 tile space) and create a new tilemap with 2 rows and cols more.

Should look for example like this:

map = new TiledMap(); // the map with the bordercells
MapLayers layers = map.getLayers();
for (int l = 0; l < map1.getLayers().getCount(); l++) {
    // create a new layer which is bigger
    TiledMapTileLayer newlayer = new TiledMapTileLayer(
            ((TiledMapTileLayer) map1.getLayers().get(0)).getWidth() + 2,
            ((TiledMapTileLayer) map1.getLayers().get(0)).getHeight() + 2,
            (int) ((TiledMapTileLayer) map1.getLayers().get(0))
                    .getTileWidth(), (int) ((TiledMapTileLayer) map1
                    .getLayers().get(0)).getTileHeight());

    // now add the cells here
    for (int x = 0; x < newlayer.getWidth(); x++) {
        for (int y = 0; y < newlayer.getHeight(); y++) {
            //add the right tile regions here!
            if(x == 0 && y == 0){
                Cell cell = new Cell();
                cell.setTile(new StaticTiledMapTile(first edge));
                newlayer.setCell(x, y, cell);
                continue;
            }

            if(x == newlayer.getWidth()-1 && y == 0){
                Cell cell = new Cell();
                cell.setTile(new StaticTiledMapTile(second edge));
                newlayer.setCell(x, y, cell);
                continue;
            }
            if(x == 0 && y == newlayer.getHeight()-1){
                Cell cell = new Cell();
                cell.setTile(new StaticTiledMapTile(third edge));
                newlayer.setCell(x, y, cell);
                continue;
            }

            if(x == newlayer.getWidth()-1 && y == newlayer.getHeight()-1){
                Cell cell = new Cell();
                cell.setTile(new StaticTiledMapTile(fourth edge));
                newlayer.setCell(x, y, cell);
                continue;
            }

            if(x == 0){ 
                Cell cell = new Cell();
                cell.setTile(new StaticTiledMapTile(textureregion for bottom here));
                newlayer.setCell(x, y, cell);
                continue;
            }

            if(y == 0){
                Cell cell = new Cell();
                cell.setTile(new StaticTiledMapTile(textureregion for first col));
                newlayer.setCell(x, y, cell);
                continue;
            }

            if(x == newlayer.getWidth()-1){
                Cell cell = new Cell();
                cell.setTile(new StaticTiledMapTile(textureregion for toprow));
                newlayer.setCell(x, y, cell);
                continue;
            }

            if(y == newlayer.getHeight()-1){
                Cell cell = new Cell();
                cell.setTile(new StaticTiledMapTile(textureregion for last col));
                newlayer.setCell(x, y, cell);
                continue;
            }
            //last but not least if none of this fit add the tile from the old map
            //dont forget the offsett
            newlayer.setCell(x, y, ((TiledMapTileLayer)map1.getLayers().get(l)).getCell(x-1, y-1)); //map1 is the original map without the borders
        }
    }
    layers.add(newlayer);
}

If you really have different tilesizes i would just add an Bordertexture for every tilesize you have in case you are using the TiledMap version. If you like to resize a Texture take a Sprite for it. A Sprite offers the .setSize(w,h) and also extends the TextureRegion. To create a Static TiledMapTile you can also add the Sprite as Texture. So if you take the idea use a Sprite and size it to the tile size before you create the StaticTiledMapTile.

Upvotes: 1

Related Questions