Click detection in a 2D isometric grid?

I have been doing web development for many years and am slowly involved in game development, and for my current project I have this isometric map where I need to use an algorithm to determine which field is clicked. This is all in a browser with Javascript, by the way.

Map
It looks like this , and I added some numbers to show the structure of the fields (tiles) and their identifiers. All fields have a center point (array x, y), on which four corners are based on the opposite. As you can see, this is not a diamond shape, but a zigzag map, and there is no angle (top to bottom), so I canโ€™t find the answer myself, given that all articles and calculations are usually based on the shape of a diamond with an angle.

Figures
This is a dynamic map and all sizes and numbers can be changed to create a new map.
I know that there is not much data, but a map is created based on the sizes of maps and fields.
- Card size: x: 800 y: 400
- Field size: 80x80 (between corners)
- The central position of all fields (x, y)

purpose
In order to come up with an algorithm that tells the client (game) in which field the mouse is located, it is in any given event (click, move, etc.).

Renouncement
I want to mention that I already came up with a working solution, but I am 100% sure that it can be written better (my solution includes many nested if statements and loops), and this is why I ask here.

Here is an example of my solution, where I basically find a square with corners in the nearest 4 known positions, and then get my result based on the smallest square between the two nearest fields. It makes sense?

Ask that I missed something.

+3
source share
3 answers

Here is what I came up with

function posInGrid(x, y, length) { xFromColCenter = x % length - length / 2; yFromRowCenter = y % length - length / 2; col = (x - xFromColCenter) / length; row = (y - yFromRowCenter) / length; if (yFromRowCenter < xFromColCenter) { if (yFromRowCenter < (-xFromColCenter))--row; else++col; } else if (yFromRowCenter > xFromColCenter) { if (yFromRowCenter < (-xFromColCenter))--col; else++row; } return "Col:"+col+", Row:"+row+", xFC:"+xFromColCenter+", yFC:"+yFromRowCenter; } 

X and Y are the coordinates in the image, and the length is the grid spacing.

Right now it is returning a string, just for testing .. the result should be a string and col, and these are the coordinates I selected: your tile 1 has the coordinates (1,0) tile 2 (3,0), tile 10 is (0 , 1), tile 11 is equal to (2,1). You can convert my coordinates to numbered tiles in a line or two.

And JSFiddle for testing http://jsfiddle.net/NHV3y/

Greetings.

EDIT: changed the return statement, had some variables that I used to debug left.

+2
source

An ideal way to detect a pixel that I have used in the past (in OpenGL, but the concept is here too) is to render the scene on-screen, where different objects are identified by different colors.

This approach requires dual memory and dual rendering, but the detection of randomly complex scenes is accomplished using a simple color search.

Since you want to detect a cell in the grid, there may be more efficient solutions, but I wanted to mention simplicity and flexibility.

0
source

This has been resolved before, let me consult my notes ...

Here are some good resources:

From Laserbrain Studios, The Basics of Isometric Programming

Useful article in a thread posted here in Java

Let me know if this helps, and good luck with your game!

This code calculates the position in the grid, taking into account the uneven interval. It should be pretty fast; almost all operations are performed mathematically using only one cycle. I will think about another part of the problem later.

 def cspot(x,y,length): l=length lp=length+1 vlist = [ (l*(k%2))+(lp*((k+1)%2)) for k in range(1,y+1) ] vlist.append(1) return x + sum(vlist) 
0
source

All Articles