Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (565) Games in Android Showcase (151) games submitted by our members Games in WIP (605) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Picking Tile in staggered isometric map  (Read 2790 times) 0 Members and 1 Guest are viewing this topic.
Xyle
 « Posted 2012-12-16 11:57:57 »

Hello!
I have been looking and trying for quite a while now, but can't seem to work out an algorithm for figuring out which tile is selected on a staggered isometric map using 64x32 tiles with a diamond shape inside.

Here is a pic of my map...

The first row is drawn, then the x is offset to the right by 32 and the next row is drawn.

Anyone have any good math skills to throw some algorithms my way for this?
Thanks for any help!

PS: My math isn't exactly top notch, so please keep that in mind.

Life is just a game, learn to play!
------------------------------------------
╬-YellzBellz Games!-╬
dapy
 « Reply #1 - Posted 2012-12-16 13:29:06 »

You can indeed solve this with a little maths.
In my isometric games, I use the following code to calculate where to draw a given tile:

 1  2 `int screenx = (int)(TILE_WIDTH * (tilex - tiley)/2.0);int screeny = (int)(TILE_HEIGHT * (tilex + tiley)/2.0);`

- screenx and screeny are the position on screen
- tilex and tiley are the tile position in the game world
- in your case, TILE_WIDTH = 64 and TILE_HEIGHT = 32
- some games may include a camera offset, but in principal they all work the same way

To determine which tile is selected on screen, you can use simultaneous equations to find tilex and tiley. Basically, make tilex the subject of the first equation, and tiley the subject of the second. I can explain this bit in more detail if you like...
Solving the simultaneous equations results in the following code:

 1  2 `int tilex = (int)(screenx/TILE_WIDTH + screeny/TILE_HEIGHT);int tiley = (int)(screeny/TILE_HEIGHT - screenx/TILE_WIDTH);`

Xyle
 « Reply #2 - Posted 2012-12-16 17:17:24 »

Thanks for the input Dapy,

I'm kind of confused on what tileX and tileY are returning in this formula...
int tilex = (int)(screenx/TILE_WIDTH + screeny/TILE_HEIGHT);
int tiley = (int)(screeny/TILE_HEIGHT - screenx/TILE_WIDTH);

are those the coordinates for the tile that was clicked?

I dont have any offsets, so I am starting my drawing at 0,0 on the screen
I am using this for drawing my tiles...
 1  2  3  4  5  6  7  8  9  10  11  12  13 `for (var i = 0; i < rows; ++i) {   for (var j = 0; j < cols; ++j) {      tTile._y = i*16;      // handle odd and even rows differently      if (i % 2) {        // Even Row        tTile._x = (j*64)+32;      } else {        // odd row        tTile._x = j*64;      }   }}`

PS: should also explain that I'm not very good at abstract logic either, hehehe.

Life is just a game, learn to play!
------------------------------------------
╬-YellzBellz Games!-╬
dapy
 « Reply #3 - Posted 2012-12-16 18:25:51 »

Yes - tilex and tiley are the co-ordinates of the clicked tile.

In my game, tile data is stored in a 2-dimensional array, something like this:

 1 `Tile[][] tileData = new Tile[TOTAL_COLUMNS][TOTAL_ROWS];`

Therefore I can access the tile data like this:

 1  2  3  4  5  6  7  8  9 `// find which tile the player has clickedint tilex = (int)(screenx/TILE_WIDTH + screeny/TILE_HEIGHT);int tiley = (int)(screeny/TILE_HEIGHT - screenx/TILE_WIDTH);// respond to the click depending on what is in that tileif (tileData[tiley][tilex] == Tile.BLOB) {  // do something to BLOB tile} else if (...) {  // ... etc etc...`
Xyle
 « Reply #4 - Posted 2012-12-16 19:19:07 »

I create my tiles from a Tile object that has individual fields. I do store the x and y of the tile, but that just references the top left corner of the 64x32 tile, where it will be drawn. Plus I would have to iterate through all tiles until that tile is matched which would still be pointing to the tiles drawing origin.

Of course this is in Flash, but the ideas are still the same. The formula for picking a tile in a diamond shape isometric map that was given by dishmoth in this post...
http://www.java-gaming.org/topics/get-row-and-col-of-mouse-click-on-isometric-map/21914/msg/252507/view.html#msg252507
worked great for the diamond shape isometric map. But trying to chop that up to make it work for a staggered isometric map is proving to be quite a challenge. The issue I believe is in the staggering of the rows.

I will keep staring at it until my eyes fall out in great goobs of goo

Life is just a game, learn to play!
------------------------------------------
╬-YellzBellz Games!-╬
matheus23

JGO Kernel

Medals: 121
Projects: 3

You think about my Avatar right now!

 « Reply #5 - Posted 2012-12-16 19:27:46 »

Danny02, where are you? ^^

See my:
My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
dapy
 « Reply #6 - Posted 2012-12-16 22:28:43 »

Ah, now I understand!
The technique I described is pretty much the same as dishmoth's - it works for 'diamond' isometric, but not for 'staggered'.

The following link explains how you might solve the problem for 'staggered' isometric maps:

http://www.gamedev.net/page/resources/_/technical/game-programming/isometric-n-hexagonal-maps-part-i-r747

Look for the heading 'Mouse Matters'.
Xyle
 « Reply #7 - Posted 2012-12-19 04:58:03 »

I appreciate the help. It being the work week, I didn't get a chance to really put some time into any solution and I definitely am not going to post the embarassing hack I was attempting.

I did get a plug and play solution involving some math equations that are quite a bit beyond me that I will post for anyone running into the same situation. It works great!

dawsonk
Maybe try something like this...

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57 `        var tileW = 64;    var tileH = 32;    var rows = 8;    var cols = 4;    for (var i = 0; i < rows; ++i) {            for (var j = 0; j < cols; ++j) {                    tTile = _root.attachMovie("Tile", "R" + i + "C" + j, _root.getNextHighestDepth());                    tTile._x = (tileW * j) + ((i % 2 == 1) ? 32 : 0);                    tTile._y = (tileH / 2) * i;            }    }    onMouseDown = function () {            var ax, ay, bx, by;            var cx = _xmouse;            var cy = _ymouse;            var posX = (_xmouse / 32) >> 0;            var posY = (_ymouse / 16) >> 0;            if ((posX % 2) == (posY % 2)) {                    ax = (posX) * 32;                    ay = (posY + 1) * 16;                    bx = (posX + 1) * 32;                    by = (posY) * 16;                    if (getPos(ax, ay, bx, by, cx, cy) < 0) {                            trace(((posY / 1 >> 0) - 1) + " : " + ((posX / 2 >>0) + ((((posY / 1 >> 0) - 1) % 2 == 0) ? 0 : -1)));                    } else {                            trace((posY / 1 >> 0) + " : " + (posX / 2 >> 0));                    }            } else {                    ax = (posX) * 32;                    ay = (posY) * 16;                    bx = (posX + 1) * 32;                    by = (posY + 1) * 16;                    if (getPos(ax, ay, bx, by, cx, cy) < 0) {                            trace(((posY / 1 >> 0) - 1) + " : " + (posX / 2 >>0));                    } else {                            trace((posY / 1 >> 0) + " : " + ((posX / 2 >> 0) +((((posY / 1 >> 0) - 1) % 2 == 0) ? -1 : 0)));                    }            }    };    function getPos(\$ax, \$ay, \$bx, \$by, \$cx, \$cy) {            // below = 1, above = -1, on = 0;            var slope = (\$by - \$ay) / (\$bx - \$ax);            var yIntercept = \$ay - \$ax * slope;            var cSolution = (slope * \$cx) + yIntercept;            if (slope != 0) {                    if (\$cy > cSolution) {                            return \$bx > \$ax ? 1 : -1;                    }                    if (\$cy < cSolution) {                            return \$bx > \$ax ? -1 : 1;                    }                    return 0;            }            return 0;    }`

Life is just a game, learn to play!
------------------------------------------
╬-YellzBellz Games!-╬
Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 theagentd (10 views) 2015-03-27 23:08:20 wxwsk8er (52 views) 2015-03-20 15:39:46 Fairy Tailz (45 views) 2015-03-15 21:52:20 Olo (28 views) 2015-03-13 17:51:59 Olo (30 views) 2015-03-13 17:50:51 Olo (35 views) 2015-03-13 17:50:16 Olo (41 views) 2015-03-13 17:47:07 ClaasJG (40 views) 2015-03-10 11:36:42 ClaasJG (41 views) 2015-03-10 11:33:01 Pippogeek (47 views) 2015-03-05 14:36:23
 LiquidNitrogen 23x BurntPizza 21x KevinWorkman 21x basil_ 20x EgonOlsen 17x theagentd 16x Roquen 16x princec 12x Riven 12x Varkas 10x SHC 9x Ashedragon 8x NegativeZero 8x phu004 7x lcass 7x ClaasJG 7x
 How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org