# Javascript Isometric draw optimization

I'm having trouble with isometric tiles drawing.

At the moment I got an array with the tiles i want to draw. And it all works fine until i increase the size of the array.

Since I draw ALL tiles on the map it really affects the game performance (obviously) :D.

My problem is I'm no genius when it comes to javascript and I haven't managed to just draw what is in viewport.

Should be fairly simple for an expert though because its fixed sizes etc. Canvas is 960x480 pixels, each tile 64x32. This gives 16 tiles on first row, 15 on the next etc. for a total of 16 rows.

Tile 0,0 is in the top-right corner. And draws X up to down and Y right to left. Going through the tiles on the first row from left to right as +X -Y.

Here is the relevant part of my drawMap()

function drawMap(){
var tileW = 64; // Tile Width
var tileH = 32; // Tile Height
var mapX = 960-32;
var mapY = -16;
for(i=0;i<map.length;i++){
for(j=0;j<map[i].length;j++){
var drawTile = map[i][j];
var drawObj = objectMap[i][j];
var xpos = (i-j)*tileH + mapX;
var ypos = (i+j)*tileH/2 + mapY; // Place the tiles isometric.
ctx.drawImage(tileImg[drawTile],xpos,ypos);
if(drawObj){
ctx.drawImage(objectImg[drawObj-1],xpos,ypos-(objectImg[drawObj-    1]));
}

}
}
}


Could anyone please help me how to translate this to just draw the relevant tiles? It would be deeply appreciated.

You need to modify your start index of the for loops so that i and j start at your current screen offset. Lets leave those at i=0, j=0 for now. (Assuming no scrolling)

Then you need to modify your end indices, map.length & map[i].length. This means you are drawing all the tiles, but like you said there is a limited amount of tiles you see, all dependent on your screen height/width.

As a starting point i would set the first for loop's end to ScreenHeight / tileH and your second for loop to ScreenWidth / tileW.

int ScreenTilesHeight = ScreenHeight / tileH + 1;
int ScreenTilesWidth = ScreenWidth / tileW + 1;
for(i = 0; i < ScreenTilesHeight ; i++)
{
for(j = 0; j < ScreenTilesWidth ; j++)
{
...


I don't know how big your canvas is so fiddle around with the + 1, until you are happy with the looks.

• Yes this far i follow, the part im stuck on is how to draw in zig zag. Like a function for odd and even rows, that i can use on the normal map array, to create a new screen array. – justanotherhobbyist Feb 27 '12 at 19:22
• I think you should either rephrase your question or create a new one. You asked "Could anyone please help me how to translate this to just draw the relevant tiles? It would be deeply appreciated." – Luis Estrada Feb 28 '12 at 2:52
• Yeah but the tiles are isometric, its not as easy as to just drawing a set number of tiles, my question is how do i go trough the array in a zig zag manner to find the tiles i need to draw. Why spam the site asking the same question twice? If you've read my full post you'll know what I asked for, and I even said how my tiles are supposed to be counted "Going through the tiles on the first row from left to right as +X -Y." – justanotherhobbyist Feb 28 '12 at 13:01
• Take a look at this post: stackoverflow.com/questions/892811/… – Luis Estrada Feb 28 '12 at 22:33

You can have your for() loops cover a rectangular area of the map which is big enough to cover the whole screen. This is a lot more tiles than you need.

Then you can further cull tiles which are off the edge (e.g. the diamond-shaped area which is outside of the screen rectangle) after you do the transformation.

If after transformation a tile is obviously off the edge of the screen, don't render it.

This is not the most "clever" or "efficient" way, but it is most likely to work.

• This is exactly what the OP is trying to ask: How do you change the given code to only draw the visible tiles? – John McDonald Mar 7 '12 at 23:45