I've created an isometric environment, all in Javascript and HTML5 (2D Canvas), which mostly works fine. The problem I'm facing is to do with having different height tiles and then sorting the indexes of objects on the tiles (in this case, while moving between two tiles side-by-side).
For example, one object may be behind a tile in front of it because the height of the tile it is on is -1. The solution I came up with was to draw each object of a tile directly after drawing the tile, starting at 0,0 and drawing each row and column from there.
This works well until I need to transition an object between two tiles. At this point, either the object must use an intermediate tile (this is what is implemented in the images below) or the tile will overlap the object as the tile is drawn after the object. Using an intermediate tile also gives a problem where the fence object on the same "row" gets draw over because the cube is using much higher z-index from the tile at 1,3 (this is slightly visible in image 1).
https://i.sstatic.net/PQJ0H.png
https://i.sstatic.net/DupM7.png
I think the tried and tested way of drawing isometric environments is just to have 1 layer for tiles and 1 layer for objects and then objects can never be behind tiles, but this is just a limitation that I don't want to adhere to.
So my question is, when drawing the entire environment from top to bottom (or any other way if it makes it possible), drawing each tile and it's objects in turn, is there a clever way to defer drawing of an object or create an array of objects to be drawn in the correct order? Has anyone else encountered similar issues and has anyone else found any solutions for this?
All help much appreciated.
An example of my tiling code:
// each column
for(y=0; y<totalColumns; y++){
// each row
for(x=0; x<totalRows; x++){
tile = tiles[y][x];
// draw tile
drawTile(tile);
objects = objects[y][x];
// draw objects for that tile
drawObjects(objects);
}
}
Edit:
One solution I have thought of (after reading the question back to myself) is to loop through all the tiles, get an array of tile heights, sort that, then do the traditional drawing. Like so:
var layers = [];
for(var y=0; y<cols; y++){
for(var x=0; x<rows; x++){
tile = tiles[y][x];
if(!layers.indexOf(tile.height)) layers.push(tile.height);
}
}
// sort layers
layers.sort(/*function here to sort layers*/);
for(l=0; l<layers.length; l++){
// draw tiles for this layer
// draw objects for this layer
}
Any other solutions possible?