Saturday, November 27, 2010

Progress, sorta

I spent all day drawing in a small booklet of graph paper trying to figure out how to go about writing a "true" isometric tile engine. This looks a little better, though not by much. I am ripping into the XNA Resources updated Tile Engine which doesn't support isometric tiles yet. This is what I've come up with for determining the origin of the tile. I'm not sure why I'm getting space between my tiles.

tileDraw.X = originOffset + (halfTileWidth * (x-y))
tileDraw.Y = halfTileHeight * (x+y)


With vertical tiles I've discovered what I'm calling "L-walls" and "R-walls". The code is different depending on which way the tile is facing. To draw an L-wall, you simply find the origin as if you were drawing a floor tile and then add this Point to it:
new Point(-halfFloorTileWidth, halfFloorTileHeight - wallHeight)

To draw an "R-wall" find the origin as if you were drawing a floor tile and add:
new Point(0, 3*halfFloorTileHeight - wallHeight)

Also I highly recommend Genetica which I used to render this door. I haven't figured out the right numbers to properly skew it so I'll be doing more experimentation. But I hope to use Genetica to generate many more high-quality tiles.

FINALLY, I've acheived isometry!

Please ignore the magenta halos around each tile, Photoshop decided to anti-alias my tile edges.

This is not a real isometric engine yet. After puzzling over the concept for days on end (surprisingly, there are no 2D isometric tile engine tutorials in XNA 4.0 yet) a brief flash of inspiration led me to realize how I could render a 2D tilemap in pseudo-isometric view. It boils down to the use of a horizontal offset (hOff). I haven't progressed very far though because I am still learning. My tile engine is based on the revived XNA Resources tutorial here.

I think I am going to change the angle so that the tiles appear to be flatter. Currently I am using tiles that I got here and then skewed in Photoshop.

Here is my Tile class:
static class Tile
{
static public Texture2D TileSetTexture;

static public Rectangle GetSourceRectangle(int tileIndex)
{
return new Rectangle(tileIndex * 192, 0, 192, 128);
//above values are hardcoded: 192 = (tileWidth + hOff)
}

}

The interesting things are in the spriteBatch.Draw parameters.

To place a tile isometrically, the destination Rectangle begins at these points:
x = (x * tileWidth) - (y * hOff)
y = (y * tileHeight)


Additionally there is a beginning offset value that I haven't coded in yet. It determines how far across the rendering field we draw our first tile (because this isn't true isometric tiling, our map is going to be a traditional matrix but rotated, with the starting tile [0][0] somewhere off to the right.)
startingOff.x = (mapHeight - 1) * hOff
startingOff.y = 0

Okay.