Mouse coordinates to tile (not 'another' topic)

Started by
26 comments, last by wicked_wesley 19 years, 11 months ago
Good day all! Before anyone asks a question, yes I did searched the forum, multiple times and I didn't find an answer. (Becuase of all the topics on this subject) Ok, I'm trying to make an Isometric engine in java (2D with and angle of 45, tiles of 70x35). I have a simple method that draws the map. The Y coordinate is drawn in a south-east direction and the X coordinate in a North-east direction (use your imagination ) :
 
   /
 X/
 /
 \   
 Y   
Edit: Finally got a picture of it: Oh, I am using a 2D array to save the map, like this (Simplefied): 1,1,1 1,2,1 1,1,1 I can't get the mouse to tile method work. This method should take the mouse coordinates as input and output the tile. I'm useing an mousemap like this: 1110222 1100022 1000002 0000000 3000004 3300044 3330444 I put the mousemap into an 2d array, so I can use it to check which tile is clicked, in a block. That's not a problem, the problem is, I can't find the 'block' which is clicked. I tried alot of things searched everywhere, but to no avail. I also read the tutorial of TANS...(forgot the rest of his name, but you probaley know who I mean ) and all the otheres here, but they all draw different, so that doesn't work for me I hope anyone out there can help me, I don't need full working programs or anything(I don't mind if you give that ), just some formulas, theory, etc. You get the point Thanks in advance! Wesley [edited by - wicked_Wesley on November 28, 2003 2:10:18 PM]
Have a nice dayWesley
Advertisement
You could take the known corner of a block(any block will do), and find the difference between the x coordinates and y coordinates of the mouse location and the block. Divide the x difference by the width of the block, and the y difference by the height of the block. This will tell you how many columns and rows over from the known block the chosen block is.
Syntax without semantics is meaningless.
Thank you for your reply

I''m going to test it out, sounds really smart

Thank you
Wesley
Have a nice dayWesley
Hey, I tested what you say, but it doesn't work Here is my source(simplefied)
//mouseX and mouseY are the coordinates of the palce hwere was clicked.mouseMapX=mouseX%68mouseMapY=mouseY%34    knownCornerX=0knownCornerY=34    tileX=mouseX-knownCornerXtileY=mouseY-knownCornerY/My tiles were 70x35, but I draw them over each other, which makes the tile 68x34tileX=tileX/68tileY=tileY/34  //Here I tweak the tile coordinates, like explained in TANS's tuturial(he calles it RegionDX and RegionDY)//*Colors based on TANS's mousemap*    int tmp=mouseMap[mouseMapY][mouseMapX];//Get the number from the mouse map       if(tmp==1)       //if clicked in red      {      tileY--      }    else if(tmp==2)  //if clicked in green      {      tileX--      }    else if(tmp==3)  //if clicked in blue      {      tileY++      }    else if(tmp==4)  //if clicked in yellow      {      tileX++      }     


I hope this is kinda readable. The x tile is wrong, it also counts the empty spots. And I can't figure out what's wrong with the Y tile. I tried alot of things, still, nothing works.

I hope anyone can help me with this
Thank you all!
-Wesley

Edit: The source only shows untill "tileY=tileY/34", is it my browser(Konqueror) or a bug?

[edited by - wicked_Wesley on November 9, 2003 7:09:28 AM]
Have a nice dayWesley
Can you post some examples of sample input and what you want the result to be? Can you show what is wrong with the Tile x and y coordinates? What do you mean by empty spots?

Your source code was readable. Maybe it is a bug in your browser?
Syntax without semantics is meaningless.
Here is the method I use for translating a mouse location on the screen to a location in the world.

First of all, my map is stored and drawn so that the X axis proceeds down and to the right, Y axis proceeds down and left.

The topmost vertex of each diamond tile obviously is the tile's origin. Each tile in the world is subdivided into some number of steps, related to pixel size of the diamond tiles in the following fashion:

TileDivs = Number of divisions (x and y) of each tile
TileWidth = TileDivs * 4
TileHeight = TileDivs * 2

So, in a game in which each tile is subdivided into 32 sub-coordinates, the tiles will be 128x64 (as Golem's are).

World coordinates are specified in the range of [0..MapWidth*TileDivs-1] and [0..MapHeight*TileDivs-1]. So in a map that is 128x128 tiles, and with TileDivs==32, the maximum (bottom right) coordinate location is (128x32)-1 or 4095.

Given a pair of world coordinates, you can find the tile those coordinates reside within:

TileX = WorldX / TileDivs
TileY = WorldY / TileDivs

And the offset (local coordinate) within the tile is found:

OffsetX = WorldX % TileDivs
OffsetY = WorldY % TileDivs

Fairly standard stuff.

Now, when I draw a map, I draw it relative to some center world coordinate location, set via a CenterAt() function. Typically, this center is set to the player's location, though it can alternatively be set to follow any object within a certain class hierarchy, including empty objects for cinematic sequences.

Now, given a knowledge of the current Map center, and a knowledge of the physical coordinates of the center of the screen (1/2 of the viewport dimensions, obviously), I can calculate the world location of any point on the screen--as long as I have the proper formulae, that is.

It took me a little bit of work, but I figured out (based upon a hazy recollection of an article I read a long time ago in Dr. Dobbs Sourcebook; IIRC, the author was Nate Goudie, but I lost that issue years ago, so I can not double check)--I figured out a set of formulae that can help me to transform screen coordinates into world coordinates and vice versa. These formulae work only for isometric setups in which the diamond is twice as wide as it is tall (128x64, 60x30, whatever).

The relevant formulae for this problem are:

DeltaWorldX = (DeltaScreenX + 2*DeltaScreenY) / 4
DeltaWorldY = (2*DeltaScreenY - DeltaScreenX) / 4

What this means is that, for each change in screen coordinates in the X direction relative to a point, the world coordinate change can be calculated accordingly, and likewise with the Y delta.

So, if you have a point on screen (the center of the viewport for our purposes), which you know corresponds to a certain point in world coordinate space (the center point set by CenterAt() ), you can subtract the center point from the current mouse location and apply these deltas to the formula. The result is a set of deltas to add to the CenterAt() world coordinate to get the world coordinate of the location of the mouse cursor.
Given: MouseX,MouseY: Current mouse coordinates CenterScreenX, CenterScreenY: Coordinate location of viewport center (1/2 the screen resolution or window size) CenterWorldX, CenterWorldY: Coordinates of map centerReturn: ClickX, ClickY: World coordinates of mouse clickProcedure: DeltaScreenX=MouseX-CenterScreenX; DeltaScreenY=MouseY-CenterScreenY; DeltaWorldX = (DeltaScreenX + 2*DeltaScreenY) / 4; DeltaWorldY = (2*DeltaScreenY - DeltaScreenX) / 4; ClickX=CenterWorldX + DeltaWorldX; ClickY=CenterWorldY + DeltaWorldY;   


Incidentally, the inverse formulae (for finding Screen Deltas given World Deltas) are:

DeltaScreenX = 2*DeltaWorldX - 2*DeltaWorldY;
DeltaScreenY = DeltaWorldX + DeltaWorldY;

So, for each change in world x coordinate of +11, the screen x coordinate will change by two, and the y coordinate will change by 1. For each change in world coordinate of +1, the screen x changes by -2, the y coordinate changes by 1. And... well, hopefully you get the idea.

EDIT: Also, I believe Konqueror currently has problems displaying the source code boxes correctly. I recommend switching to Mozilla (runs well on Linux, and is generally more powerful than Konqueror).

Josh
vertexnormal AT linuxmail DOT org

Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.


[edited by - VertexNormal on November 9, 2003 9:44:58 PM]
Something related: I''m working on an elevated iso-tile engine, like the tiles in Roller Coaster Tycoon, et al., so how I''m going to be able to convert mouse clicks to map positions is something that concerns me. I''m thinking of having a pointer map correpsonding to each pixel on screen that is generated along with the draw function of each tile. That way I can look up the mouse coords as indicies in that map to find out which tile it points to. Then I''ll have to have some other funky function (which I''ve already written, mind you) convert to the location on the tile. Something to think about. If anyone has any suggestions I''d like to hear them.


Image loads when I''m online!The following statement is true. The previous statement is false.
Shameless promotion:
FreePop: The GPL Populous II clone.
My stuff.Shameless promotion: FreePop: The GPL god-sim.
That''s basically what I''m doing in my game to allow the player to select the objects in the cells even if the objects overflow the boundaries of the cells (visually, not in the game world). Basically I create an RGB out of the cell coordinates. Then I paint the cell and cell contents in that color into a special "pick-map." Then when the user clicks the mouse, I look up the mouse coordinates in the pick map, grab the RGB, unroll it into cell coordinates, and look THOSE up in my game map structure thingy.

Obviously if you have more than one selectable object in a cell you need to draw it in two colors. Of course since you''ve only got two dimensions and 3 colors in an RGB triple, that extra color is free for use, specifically 256 different selectable objects/regions per cell! Not bad, really.
Hi there,

First of all, thank you! Sorry I didn't replied so soon to this topic, but I wasn't able to be on my computer, so sorry about that. VertexNormal, I tried what you have posted, but I didn't work I tried like 10000 million different ways, but none seem to work.

Now I have thought up another way to calculate the tile. I haven't figured out everything yet, but I think it will work. I will try to post my new idea, but I'll first try to get it work, hey I might even write a (short) tutorial about the development of the Iso basics

I don't think I should even try elevated tiles, hehehe I know Mozilla renders faster (even faster than IE) but Konqueror is also my filebrowser and I have to habit to check these forums all the time

Thank you for your help, I shall post my idea as soon as I have some pictures of it (it's too hard for me to explain in my own language (Dutch), so leave alone English :D)

Regards,
Wesley

[edited alot by - wicked_Wesley on a couple of mins after the post]


[edited by - wicked_Wesley on November 22, 2003 6:21:31 PM]
Have a nice dayWesley
I found by far the easiest method for converting the mouse to tile is to check this in the map drawing routine itself.

if (readpixel(point(tx,ty)) <> trans_color)
mappoint(x,y) = point(x,y);

Why do it the hard way?

This topic is closed to new replies.

Advertisement