Reputation: 1330
We're working on a Javascript game that is developed and defined based on 2D board coordinates.
We are trying to convert the X,Y coordinates that we currently have (ie, 0,0) into the corresponding ISO coordinates for use with crafty.js.
The reason we are doing this is because the server randomly generates a game board that is a traditional 15x15 grid of spaces, and we would like to render it in isometric 3D, but crafty JS uses a strange coordinate system that starts in the upper left of the screen.
How would we map a 2D grid to the following image, with the upper left board space mapping to either (0,6) or any of the ? annotations?
Upvotes: 3
Views: 2663
Reputation: 1620
//Cartesian to isometric:
isoX = cartX - cartY
isoY = (cartX + cartY) / 2
//Isometric to Cartesian:
cartX = (2 * isoY + isoX) / 2
cartY = (2 * isoY - isoX) / 2
Upvotes: 0
Reputation: 1428
I'm working in crafty as well, attempting to make a 17x17 board. Currently I'm simply using a map to covert every location to it's corresponding Crafty location. I realize it's incredibly hacky, probably slow, but I honestly don't have time.
I noticed above that the numbers are a bit off in the image above. Here's a little better visualization of how Crafty works in this situation. The white numbers are the raw data I get from the server, and the black numbers are what Crafty needs to render this board:
I've basically worked it out to a somewhat useful equation (but only useful when creating the map):
Even rows (starting at 0)
- y (row) = starting at row number (base 0) then increment by 1 for each x (column)
- x (col) = previous odds's first x, then follow pattern: +0, +0, +1, +1, +2, +2...
Odd rows (starting at 0)
- y (row) = starting at row number (base 0) then increment by 1 for each x (column)
- x (col) = +1 to previous even's first x, then follow pattern: +0, +1, +1, +2, +2, +3...
So I have a map below that seems to work (this is the rawToCrafty map):
//Row 0
"00.00": { "y": 0, "x": 8 }
"01.00": { "y": 1, "x": 8 }
"02.00": { "y": 2, "x": 9 }
"03.00": { "y": 3, "x": 9 }
"04.00": { "y": 4, "x": 10 }
"05.00": { "y": 5, "x": 10 }
"06.00": { "y": 6, "x": 11 }
"07.00": { "y": 7, "x": 11 }
"08.00": { "y": 8, "x": 12 }
...
Yes there are better ways, but this is the brute force way. Good luck!
Upvotes: 1
Reputation: 3064
If I've understood correctly you want to map the following input onto the following output:
Input:
0,0 0,1 0,2 0,3 0,4 0,5
1,0 1,1 1,2 1,3 1,4 1,5
2,0 2,1 2,2 2,3 2,4 2,5
3,0 3,1 3,2 3,3 3,4 3,5
4,0 4,1 4,2 4,3 4,4 4,5
5,0 5,1 5,2 5,3 5,4 5,5
Output:
0,6 0,5 1,4 1,3 2,2 2,1
0,7 1,6 1,5 2,4 2,3 3,2
1,8 1,7 2,6 2,5 3,4 3,3
1,9 2,8 2,7 3,6 3,5 4,4
2,10 2,9 3,8 3,7 4,6 4,5
2,10 3,10 3,9 4,8 4,7 5,6
My matrices are pretty rusty. I'm sure there'll be a tidy way to use them to do this, but I'll give you my hacky answer.
Assuming this isn't an instance of a more general problem you could do something like:
function mapCoords(xIn,yIn){
return {
x:Math.floor((xIn+yIn)/2),
y:6+xIn-yIn
}
}
There'll be generalisations to make, and more elegant ways of doing it, but to my understanding this solves your example.
Upvotes: 0
Reputation: 10579
The name for this general concept is Projection.
To draw the game board onto the screen, you project from game board coordinates to screen coordinates.
To take the mouse click location and determine what location on the board was clicked, you project from screen coordinates to game board coordinates.
These two projections are the inverse of each other.
A common way to perform these projections in game programming is to use a matrix.
Upvotes: 0