View Full Version : Having trouble converting from mouse to isometric
doomtoo
July 15th, 2009, 07:20 PM
I'm having a lot of trouble being able to tell which tile the mouse is over. In the past I had found equations of the lines that make up the slopes of the tile, and checked if the point was in there, but converting coordinate systems sound simpler.
In an old post:
pixel_x = X_LOCATION_OF_TOP_MIDDLE_TILE + 64*tile_x - 64*tile_y
pixel_y = Y_LOCATION_OF_TOP_MIDDLE_TILE + 32*tile_x + 32*tile_y
now to do the screen --> tile
for ease of writing, pixel_x = px, tile_x = tx, X_LOCA... = X0
equation1: px = X0 + 64*(tx-ty)
equation2: py = Y0 + 32*(tx+ty)
we want to find equations for tx and ty when given px and py, so we do some algebra:
eq1+2*eq2 = px+2py = X0+2Y0 + 128*tx
---> tx = (px+2*py -X0-2Y0)/128
eq1-2eq2 = px-2py = X0-2*Y0 -128ty
---> ty = (px-2py - X0+2*Y0) /(-128)
how does he get the assumption that
eq1=-2*eq2
and
eq1=2*eq2
And this formula does not work at all for mine-
using:
(px=point to draw at, x=first loop, y=second loop, H=height of tile=Width/2)
px=(x-y)*H
py=(x+y)*H/2
therobot
July 15th, 2009, 09:39 PM
I might suggest you go over these tutorials:
http://www.tonypa.pri.ee/tbw/tut16.html
He covers isometrics really well and addresses converting coordinates to isometric. Plus its a fun read anyways, so if you haven't read it, read it 8)
doomtoo
July 15th, 2009, 10:36 PM
Yeah, I had finally found that and it looked really good, except the I dont know the syntax.
//convert mouse coordinates from isometric back to normal
var ymouse = ((2*game.clip._ymouse-game.clip._xmouse)/2);
var xmouse = (game.clip._xmouse+ymouse);
//find on which tile mouse is
game.ymouse = Math.round(ymouse/game.tileW);
game.xmouse = Math.round(xmouse/game.tileW)-1;
//place mouse mc
_root.mouse._x = (game.xmouse-game.ymouse)*game.tileW+game.clip._x;
_root.mouse._y = (game.xmouse+game.ymouse)*game.tileW/2;
which mouse is which?
game.clip._xmouse
game.xmouse
xmouse
_root.mouse._x
game.clip._x
therobot
July 15th, 2009, 10:59 PM
game.clip._xmouse
the actual mouse coordinates (relative to the movieclip that holds your game). game is an object, clip a property of game that points to the movieclip that holds your game.
game.xmouse, game.ymouse
this should be the tile coordinates for the tile that is under the mouse
xmouse & ymouse
temporary vars
_root.mouse._x
_root.mouse is a movieclip in this tutorial i believe. If you look at the example files, i think it is the red box you see as you mouse over tiles
game.clip._x
this is the coordinates of the movieclip that holds your game.
the real meat of it is:
//convert mouse coordinates from isometric back to normal
var ymouse = ((2*game.clip._ymouse-game.clip._xmouse)/2);
var xmouse = (game.clip._xmouse+ymouse);
//find on which tile mouse is
game.ymouse = Math.round(ymouse/game.tileW);
game.xmouse = Math.round(xmouse/game.tileW)-1;
the other bit is optional/gratuitous.
doomtoo
July 15th, 2009, 11:25 PM
Thanks!
Using the original formula I posted(from a previous thread), I was able to get it to tell which tile I was on, but it is kind of jumpy(if the mouse is dead center on a tile it is correct, but slightly off centered it picks up one of the neighboring tiles)
I also realized I could solve it for myself and it works the same when implemented, but still not right on target.
(Xc,Yc= screen Cartesian coordinates, Xi,Yi=isometric coordinates, h=tileheight)
Starting with the formula I used to draw:
Xc=(Xi-Yi)*h
Yc=(Xi+Yi)*(h/2)
solving for xi and yi=
Xi=Xc/h+Yi
Yi=Yc*(2/h)-Xi
plugging Yi into the 1st equation=
Xi=Xc/(2h)+(Yc)/h
Yi=Yc*(2/h)-Xc/(2h)+(Yc)/h
Which like I said can tell roughly what time the mouse is over, but only when the mouse is over it's center, otherwise it thinks it's over a different one.....
got the one from the tutorial working somewhat, but it seems to think the tiles are much bigger than they are(doesn't detect me moving onto the next tile until after 2.5tiles or so)
var pointer_y_temp:int=((2*pointer_y-pointer_x)/2);
var pointer_x_temp:int=(pointer_x+pointer_y_temp);
var tile_y:int=Math.round(pointer_y_temp/tilewidth);
var tile_x:int=Math.round(pointer_x_temp/tilewidth)-1;
wierd- changed his from dividing by the width to the height, and it works perfectly! But what is wrong with my equation?
(Thank you 1000 times!!! This has been giving me a headache, and was going to just go back to looking for the point under the slopes if I could not get it to work!)
Any idea?
doomtoo
July 15th, 2009, 11:38 PM
My equations (that work but only accurate on the center of the tile):
var tile_x:int=(pointer_x)/(2*tileheight)+(pointer_y)/tileheight;
var tile_y:int=(pointer_y)*(2/tileheight)-tile_x;
and his (modified to use height instead of width)
var pointer_y_temp:int=((2*pointer_y-pointer_x)/2);
var pointer_x_temp:int=(pointer_x+pointer_y_temp);
var tile_y:int=Math.round(pointer_y_temp/tileheight);
var tile_x:int=Math.round(pointer_x_temp/tileheight)-1;
doomtoo
July 15th, 2009, 11:51 PM
seems to be a rounding problem! Simplified his equation, behaves exactly the same without rounding. Now to figure out where/why to round....
My simplified equns:
Xi=Xc/2h+Yc/h
Yi=Yc/h-Xc/2h
His:
Xi=Xc/2h+Yc/h-1
Yi=Yc/h-Xc/2h
and they behave exactly the same!?
How does he know what to round to?
doomtoo
July 19th, 2009, 05:19 PM
Anyone have any ideas? It doesn't seem to work with scrolling- when I had my tile[0].x positions to the equation, it ends up being a tile off!
Anyone have any actionscript 3.0/c++/java examples? Or even a basic solution to converting mouse coordinates to isometric? I'm missing something, but I just don't get it.
My previous way was to make 2 equations for each diamond, and look to see if the point clicked was less than the slope of both points, but I would have to iterate through all diamonds, or at the very least, all diamonds on screen, which would be a lot more processor intensive then this technique, if I could actually get this to work!
doomtoo
July 19th, 2009, 06:16 PM
Yay, finally found a solution that actually works properly!
at:
http://www.allegro.cc/forums/thread/204075
(circa 2002)
it was simple as just converting the tile size to sceen size (from what I can see). Mine was 1 off, so I minused one and rounded to (because you can't be at tile (0,.2))
tile_x=Math.round((pointer_x+scrolledX)/tilewidth+(pointer_y+scrolledY)/tileheight)-1;
tile_y=Math.round(-(pointer_x+scrolledX)/tilewidth+(pointer_y+scrolledY)/tileheight);
Works perfectly with scrolling ect. Less work than my original solution! If anyone knows how to explain how to come up with this from scratch, let me know!
Powered by vBulletin® Version 4.1.10 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.