Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've been looking for a formula to plot (world->screen) and mouse pick (world->screen) isometric tiles in a diamond-shaped world. The ones I've tried always seem to be, well, off. What's the usual/correct way to do this?

share|improve this question
    
The exact method and formula used depends a bit on the shape of your tiles, and probably a bit on how you're drawing the map (is 0,0 on the top, bottom, or one of the sides of the map) More details about your problem would help. –  thedaian May 16 '11 at 17:25
1  
Tiles are 2:1 (more specifically, 64x32). The coordinate system doesn't matter since I'm writing the editor. (0,0 at the top or left seems sensible however.) –  mpnk121 May 16 '11 at 23:11
    
Very late to the question and I don't even have a complete answer, but there was a very good Google Tech Talk on this precise subject. Their setup includes picking the non-transparent portion of arbitrary images (in javascript, no less). youtube.com/watch?v=_RRnyChxijA –  Seth Battin Mar 6 '13 at 6:04

1 Answer 1

up vote 16 down vote accepted

Based on your comment, here's the code I'm using to convert tile x,y values to on screen coordinates. Now, it doesn't take into account "3d tiles", everything is considered as being on the same plane, so if you're writing a game where that matters, this code will not work.

//this converts a map x/y coordinate into screen coordinates
//public, static method, so can be called outside the Tile object
point Tile::convertToScreen(int x, int y, int offsetX, int offsetY)
{
        point screen;
        //calculate the screen coordinates
        //note: these will then be modified by the camera
        screen.x = offsetX - (y * TILE_WIDTH/2) + (x * TILE_WIDTH/2) - (TILE_WIDTH/2);
        screen.y = offsetY + (y * TILE_DEPTH/2) + (x * TILE_DEPTH/2);
        return screen;
 }

point is simply a structure containing x and y ints, TILE_WIDTH would be 64 in your case, TILE_DEPTH is kind of badly named (it is actually the height of the tile graphics), but it would be 32 in your case. The offsets are if you want your tile map to "start" at a different x,y location (such as if you want tiles to be above another set of tiles). Typically the offset can be 0,0.

This will generate a map with 0,0 on top, middle, like this:

        0,0
    0,1     1,0
0,2     1,1     2,1

As for finding the tile x,y of the cursor:

point selectedTile;
int x = mX - camera.x;
int y = mY - camera.y;
selectedTile.x = (y + x/2)/TILE_DEPTH;
selectedTile.y = (y - x/2)/TILE_DEPTH;

In this bit of code, mX and mY are the mouse screen coordinates, which we're combining with the camera values to find out where we are in "world coordinates". Everything else is the same as the previous code example.

Once again, this assumes a flat 2d isometric tile map. There's some additional work if you want to use a semi-3d view of the map, and this all assumes that you're working in 2d anyway.

share|improve this answer
1  
Thank you! - this works great for flat maps. Now, can you tell me a bit more about how I could add arbitrarily sized (i.e. with a Z depth) tiles that are on another layer? (Such as props like a well, or a streetlight) –  mpnk121 May 17 '11 at 4:06
2  
That's when you use the offsetY and offsetX values. If your streetlight is 64x64, then passing in a negative 32 for the offsetY value should make it appear at the right place. Hopefully that's enough to get you started. –  thedaian May 17 '11 at 12:33
4  
Shouldn't the coordinate "2,1" in your example be a "2,0" ? –  Chris Mar 7 '12 at 13:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.