[Libgdx]Tilemap rendering issue

:o
That sounds complicated, I didn’t know rendering a tilemap would be such a nightmare to code.
I’ve got another idea but I don’t know if it would work. You told me a few days ago that if trees could be drawn as a single entity it would make the rendering order much easier.
But tiles can also be “grouped”. I can create TileGroup class that contains a list of tile ids and its relative positions to a root tile, then I add a new array of shorts in my tilemap which links to these TileGroup instances. That way I can get the root tile position and sort with it.

In comparator :


float y = drawable.getY();
if(drawable.isGroup) {
   y = tileMap.findRootTileY(drawable.getGroupId(), drawable.getX(), drawable.getY());
}

What do you think ?

I don’t know if it’ll work out because i don’t know what content and features you’re trying to squeeze into it.

From what I’ve seen it seems like you don’t even need multiple layers.
You’d be better of just drawing a ground layer, then the objects + players layer combined and sorted by Y and call it a day.
This will enable you to do basically the same thing as in the video below, you need to merge your sprites though.

A single layer and entities would be good for a simple map, not if I want to add buildings/bridges/big trees on top of the terrain layer. The object layer isn’t only for simple “objects”. The terrain layer is separated from the rest because I want several ground types (grass, ice, desert etc) and transitions are easier to achieve this way.

the funny thing is that all your solutions are probably more costly overall than having a few extra batch-renderings on the GPU side :slight_smile:
the way I did it in Heroes of Loot 2:

  1. batch render the floor tiles (only floor tiles)

  2. batch render floor-effects (blood, debris, etc)

  3. batch render all images (monsters, players, objects) which are sorted from top to bottom (sorted on y+object-height which is at their “feet” location).

  4. batch render the walls

results are:

http://techblog.orangepixel.net/wp-content/uploads/2016/03/forum_hol2_screenshot02.png

the game uses on average 16 batch calls (includes statusbar layer, light-layer, etc) and runs fine on 2 year old android+ios devices

however I do use raw tilemap rendering, nothing LibGDX specific. So it’s just " for x = left to right; for y = top to bottom; drawTile"

to enhance that even more I could use pre-rendering the floor tiles and the wall-layers, but that wasn’t really needed.

Congrats for your game, it looks very good and the art style is beautiful :slight_smile:

As for the rendering process, that’s what I’m doing, but with a few differences :

  1. batch render terrain layer (grass, sand, snow etc)
  2. add every tiles from lower&upper layers in render queue
  3. add every entities in render queue
  4. sort by Y and Z
  5. batch render everything

This is probably more costly than your system, but not for the logic part. Imagine you need a huge house on top of your terrain layer with the ability to go behind it (the upper part being drawn on top of the players if they’re behind this house). If you draw it as an object entity (a single sprite), you’d have to code a heavier collision system or even use a physics engine when the shape becomes complex (not a basic rectangle). With the houses, trees (and other things) stored as multiple tiles, I only need to do a simple check on the cell and everything becomes much easier :


if(tileMap.getCellCollider(x, y, LOWER_LAYER)) {
 	// I can't go there
}

if(tileMap.getCell(x, y, LOWER_LAYER) == DOOR_HOUSE_ID) {
      // enter the house
}

if(tileMap.getCellGroupId(x, y, LOWER_LAYER) == GROUP_TREE_ID) {
   // I can cut down this tree
}

actually I don’t need to do any extra check on that either, my map layer is split into a 1/0 layer for the solid/empty tile information
and a render-layer that keeps track of which tile to draw (and this is auto-generated from code based on the 1/0 layer)

and when I initialize the world and place a house or big-statue like I have in my game, I set solid-flags for all the tiles I want blocked.
all my game objects have a standard collision detection with the tile layer, so it doesn’t cost anything extra on having 40 houses or 0 houses on the map either.

all it requires is a bit of extra memory for having two arrays for the world instead of one

What if your big-statue/house gets (partially or not) removed/destroyed ? How do you update your collision flags and your visuals ?

you just modify the solid layer and set new 1/0 flags. optionally you also modify the render-layer underneath (which is millisecond work)
as for the visuals, your object will then use a new sprite frame showing it’s new destroyed state (or it get’s killed and removed from the object list completely, setting 0’s at it’s tile location)

Ok so you keep track of the tile locations in your objects. Good idea, I’ll try your system and see if it works well with my project. Thank you for your explanations :slight_smile: