23
\$\begingroup\$

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?

\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$
    – thedaian
    Commented May 16, 2011 at 17:25
  • 1
    \$\begingroup\$ 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.) \$\endgroup\$
    – mpnk121
    Commented May 16, 2011 at 23:11
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Mar 6, 2013 at 6:04

1 Answer 1

21
\$\begingroup\$

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.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ 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) \$\endgroup\$
    – mpnk121
    Commented May 17, 2011 at 4:06
  • 2
    \$\begingroup\$ 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. \$\endgroup\$
    – thedaian
    Commented May 17, 2011 at 12:33
  • 7
    \$\begingroup\$ Shouldn't the coordinate "2,1" in your example be a "2,0" ? \$\endgroup\$
    – Chris
    Commented Mar 7, 2012 at 13:45
  • \$\begingroup\$ I had to extract (y + x/2) as xx and (y - x/2) as yy to later do if (xx > 0) return null; and if (yy < 0) return null; in order to fix the extra area to the left (top left and bottom left diagonally) where my tiles were selected \$\endgroup\$ Commented May 28 at 3:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .