Here’s a link to an Applet ( source included ) so you can see the stuff discussed in action:
http://i.imgur.com/QOGWC.png
SOURCE: http://jonjavaweb.orgfree.com/IsoWorldSource.zip
In Normal tiled games, maps/rooms/worlds are saved and portrayed through a 2d Array like this:
Isometric games are practically no different in how these maps/rooms/worlds are stored. The most notable difference is, of course, how these maps/worlds appear on screen. This is achieved through different projection. I.e, the same 2d Array, just viewed differently. This is mostly done by turning the tiled map 45 degrees in either direction and substituting the tile with a new isometric tile image.
There are different ways and styles on how you can draw isometric tiles. However, this doesn’t matter in calculations. What matters is the width and height of the isometric tile. NOTE: Not always the same as the Images width or height.
Here we have a Sprite/Image of a pink isometric tile that is 34 pixels wide and 17 pixels high. However, this tile’s intended Width and Height are 32 and 16 respectively. Notice the jagged lines that are produced when using the Images Width/Height instead of the intended Isometric Tile Width/Height.
A 2d Array projected Isometrically
Let’s start by going through the array and figuring out the isometric coordinates. We will calculate the isometric position of the blue (Top Left) corner for each tile.
Let’s insert the isometric projection into a coordinate system and see what conclusions we can draw from it.
[EDIT]: Added Formula to convert Isometric positions back to 2D-Array positions.
In this case we have a screen whose Top Left corner points to a tile (pink!). Now even if the screen moves around a bit, the Top Left corner still points to the exact same tile!
Now that we can find out where to draw the isometric tiles based on the 2d Array, let’s try it out:
Half the tiles are off-screen! To fix this issue we need to add a Horizontall Offset and Vertical Offset Variable. The hOffset makes sure no tile is draw behind the screen to the left, and the vOffset drags all the tiles down so it’s easier on the eyes:
Now here’s my question! Consider a large map
How do I make sure to draw only the tiles within the screen as to not waste memory cpu (less iterations)? The map is stored in a 2D Array.
I’ve fiddled around with my own solution for days now and it just doesn’t work. I need some fresh ideas.
public void paintDiamond(Graphics g, int x, int y, int w, int h) {
// Paint a diamond shape taken from the 2D surface array
// shows up as a rectangle in isometric view
/* [ i ]
* x *
* x x *
* x x x * [ j ]
* x x *
* x *
*/
int px = x/Tile_W; // position x
int py = y/Tile_H; // position y
int dpw = (w - x) / Tile_W; // delta position width
int dph = (h - y) / Tile_H; // delta position height
for(int i=px; i<dpw; i++) {
for(int j=px; j<i; j++) {
//TODO
colArray[i][j].paintAll(g);
}
}
}
Basically only the highlighted tiles should be drawn