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'm trying to implement mouse interaction in a 2D isometric game, but I'm not sure if it's possible given the coordinate system used for tile maps in the game.

I've read some helpful things like this. However, this game's coordinate system is "jagged" (for lack of a better word), and looks like this:

Example

Is it even possible to map mouse coordinates to this successfully, since the y-axis can't be drawn on this tile-map as a straight line?

I've thought about doing odd-y-value translations and even-y-value translations with two different matrices, but that only makes sense going from tile to screen.

share|improve this question
    
"new users can't post images.. so I'll try to draw it w/ coordinate values" - if it's possible, you can provide a link to an image (you can use something like imgur). Then someone with more rep could put the images directly into the post. –  fableal Oct 5 '12 at 13:57
    
Can you add this image to the original post, please? i.imgur.com/ggFoy.png –  plukich Oct 5 '12 at 14:05
2  
Why are your tiles given those coordinates? I mean sure you could map mouse coordinates to tiles that way, but why? –  jhocking Oct 5 '12 at 14:26
    
@jhocking it was probably easier for him to draw it like this. –  Markus von Broady Oct 15 '12 at 22:17
add comment

3 Answers

Screen-space mouse coordinates to tile coordinates

The general dimetric projection matrices in my answer to the question linked above will get you the transformation from screen coordinates to tile coordinates. In particular, this matrix can be used for transformation of the screen coordinates to tile coordinates:

The values to input are:

  • w: half of the width of a single tile on screen
  • h: half of the height of a single tile on screen
  • fx: X-Position of the upper corner of the (0,0) tile in screen coordinates
  • fy: Y-Position of the upper corner of the (0,0) tile in screen coordinates

The mouse coordinates have to be extended by a constant value of 1 to be a 3-dimensional vector (xmouse, ymouse, 1) and multiplied by this matrix to arrive at the tile coordinates.

Tile coordinates to tile indices

Unfortunately if you apply them straight away to your image, you'll find that the actual tile indices aren't quite in line with their coordinates.

enter image description here

The somewhat thicker green lines in the picture are at coordinates x=0 and y=0; the others are spaced one unit of length apart. Remember that the y coordinate goes down as usual with computer graphics, so the tile indexed by (1,0) is in the tile with coordinates x=[1, 2) and y=[-1, 0).

Given the "normal" integer tile coordinates x and y (in blue on the picture above), you can calculate your tile indices xind and yind with the following formulas(1):

xind = floor(x - y + 1)/2)

yind = x + y


(1) In this context, the floor() function rounds down towards -∞.

share|improve this answer
    
Can you provide any further information about the derivation of the transformation matrix you have listed here? Where does it come from? Do you have a link or a book? –  Andrew Austin Mar 10 '13 at 4:24
    
@AndrewAustin I linked the derivation at the start of my answer, but here is the link again. What you do is to calculate the inverse matrix of the tile-space to screen-space transformation matrix. Check any basic geometry book which has a chapter about projections for details. –  Martin Sojka Mar 13 '13 at 11:48
add comment

If it's still not working, these tutorials may be of help:

http://www.gamedev.net/page/resources/_/technical/game-programming/isometric-n-hexagonal-maps-part-i-r747 , http://www.wildbunny.co.uk/blog/2011/03/27/isometric-coordinate-systems-the-modern-way/

share|improve this answer
    
The first one assumes a constant tile size (on screen), the second one assumes a sane coordinate system. Both are good articles, mind you. –  Martin Sojka Oct 17 '12 at 9:03
add comment

Yes, it is possible, the easiest way would be to draw a 2d-array numerical representation of the tiles, where each tile 'pixel' in the array is coded with a serial tile number.

Otherwise

Here is the complete answer:

Assuming each tile is defined by this height and width properties:

TILE_WIDTH = xyz;
TILE_HEIGHT = abc;

And the game map looks like this:tile map We first make sure that anything on the green and red triangles is the '0' tile. Meaning a tile that does not exist.

We have as input the mouse (x, y)

offsetY = (mouseY - 0.5 * TILE_HEIGHT) % TILE_HEIGHT;
greenPixels = TILE_WIDTH * Math.abs(TILE_HEIGHT/2 - offsetY) / TILE_HIGHT;

offsetX = mouseX % TILE_WIDTH;
redPixels = TILE_HEIGHT * (TILE_WIDTH/2 - Math.abs(TILE_WIDTH/2 - offsetX)) / TILE_WIDTH;
if(mouseX < greenPixels || mouseY < redPixels) return (0,0);
else
{
    rowY = (int) Math.floor((mouseY -0.5 * TILE_HEIGHT) / TILE_HEIGHT);
    columnX = (int) Math.floor((mouseX * TILE_WIDTH) / TILE_WIDHT);
    if( (offsetX / TILE_WIDTH) + (offsetY / TILE_HEIGHT) < 1.0) return (columnX, 2 * rowY - 1);
    else
    {
        if(offsetX < TILE_WIDTH / 2) columnX --; // columnX = columnX - 1
        if(offsetY < TILE_HEIGHT / 2) return (columnX, 2 * rowY - 2);
        else return (columnX, 2 * rowY);
    }

}

This is the general pseudo code you need, there might be typos and you are welcome to ask questions and I will elaborate.

Generally what I did is build an imaginary square grid over the even rows of the tiles - ie the second row, the fourth row and such.

enter image description here

Then I check in which of this grid's squares the mouse is pointing (which is relatively simple since it is not jagged like the tiles.

Now I check the distance on x and y from the center of the square grid. If the pointer is not far enough from the center of the tile(which is also the center of the square in the grid) it is inside the tile.

Done like in this question:

Checking if an object is inside bounds of an isometric chunk

If not, if it is too high, it is one row above, if it's too low, it is one row below, if it is too much to the left, it is one column behind (cause the tiles on the un-even rows start a little later than the ones on the even rows) and if it is too much to the right than it is in the same jagged column as the even tile in the center.

share|improve this answer
    
There is a problem with calculating the x column position in this line, it will just follow the mouseX position with no modification I'm trying to fix this currently columnX = (int) Math.floor((mouseX * TILE_WIDTH) / TILE_WIDTH); –  Pent Oct 16 '12 at 2:18
    
I fixed the calculation by multiplying 0.25 to the tile width in offsetX and columnX –  Pent Oct 16 '12 at 4:47
    
I honestly did not really bug test, does it work now? –  Arthur Wulf White Oct 16 '12 at 7:52
    
it "kind of" works, the mouse accuracy is poor, so I think there is still some tweaks to do –  Pent Oct 16 '12 at 17:24
add comment

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.