Reputation: 45
I'm not all that good with Maths, so i was hoping some of you guys could help?
I'm trying to make a function to convert mouse coordiantes into a particular tile in an isometric view.
It won't let me post images for a stupid reason, so ill just link the image:
All of the algorithms i have seen so far work with the X & Y axes going diagonal, my game is currently set up like this, and i would like to keep it so.
Is there an algorithm so that if the mouse was at the red dot, it would return the coordinates of the tile that it is sitting on? (6,2)
Thanks in advance!
Upvotes: 1
Views: 1639
Reputation: 8584
It's quite easy actually once you get your head wrapped around it. All you do is find out where your mouse is relative to the map and then reverse to how you are drawing the tiles.
I draw my map in the double "for" loop like this:
For x coord: x * (TileWidth / 2) - (y * (TileWidth / 2))
For y coord: x * (TileHeight / 2) + (y * (TileHeight / 2))
So my x goes from top left to bottom right and my y goes from top right to bottom left. Mind though, like for the first tile the world coord will be 0,0 but the top pixel starts at x=0 + (tilewidth / 2) so we have to compensate for that when we are looking to find which tile the mouse is over. (or we could do that for the whole world itself by giving it a offset).
Now first we have to find the mouse position in relation to the world since you probably want a moving camera. My camera's centre starts as 0,0 so i have to compensate the mouse by half the screen width like so:
mouseWorldPosX = mouse.x + cam.x - (screen.width / 2)
mouseWorldPosY = mouse.y + cam.y - (screen.height / 2)
This is all we need to calculate the mouse position back to tile position.
For X:
tileX = (mouseWorldPosX + (2 * mouseWorldPosY) - (tileWidth / 2)) / tileWidth
As you can see we divide the whole thing by the tilewidth since we multiplied it in the draw method. The (tileWidth / 2) is just there to compensate for the offset i mentioned earlier.
For Y:
tileY = (mouseWorldPosX - (2 * mouseWorldPosY) - (tileHeight / 2) / -tileWidth
It's practically the same but the other way around. We subtract the Y world position since the Y axis runs the other way around. This time we compensate the offset for the height of the tile and we divide the whole thing by negative tilewidth, again since it runs the other way.
I hope this helps below is a working example of a method i looked up, it returns a vector with the tile coordinates:
public Vector2 MouseTilePosition(Camera cam, GraphicsDevice device)
{
float mPosX = newMouseState.X + (cam.Position.X - (device.Viewport.Width / 2));
float mPosY = newMouseState.Y + (cam.Position.Y - (device.Viewport.Height / 2));
float posx = (mPosX + (2 * mPosY) - (Map.TileWidth / 2)) / Map.TileWidth;
float posy = (mPosX - (2 * mPosY) - (Map.TileHeight / 2)) / -Map.TileWidth;
return new Vector2((int)posx, (int)posy);
}
Upvotes: 0
Reputation: 59
<0;4>
x <0;3> <1;4>
<0;2> <1;3> <2;4>
<0;1> <1;2> <2;3> <3;4>
<0;0> <1;1> <2;2> <3;3> <4;4>
<1;0> <2;1> <3;2> <4;3>
<2;0> <3;1> <4;2>
y <3;0> <4;1>
<4;0>
I rendered the tiles like above.
the sollution is VERY simple!
first thing:
my Tile width and height are both = 32 this means that in isometric view, the width = 32 and height = 16! Mapheight in this case is 5 (max. Y value)
y_iso & x_iso == 0 when y_mouse=MapHeight/tilewidth/2 and x_mouse = 0
when x_mouse +=1, y_iso -=1
so first of all I calculate the "per-pixel transformation"
TileY = ((y_mouse*2)-((MapHeight*tilewidth)/2)+x_mouse/2;
TileX = x_mouse-TileY;
to find the tile coordinates I just devide both by tilewidth
TileY = TileY/32; TileX = TileX/32;
DONE!! never had any problems!
Upvotes: 1
Reputation: 1204
There is a good start : http://www.java-gaming.org/index.php?topic=23656.0
Enjoy :)
EDIT
Full-trusted "DrDobb's" website, full article on this : http://www.drdobbs.com/parallel/designing-isometric-game-environments/184410055
Upvotes: 2