Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Mouse Over IsometricTiles

This thread is locked; no one can reply to it. rss feed Print
Mouse Over IsometricTiles
dakatt
Member #10,695
February 2009

I'm trying to think of a way of determining whether the mouse is currently over an isometric tile without selecting the adjacent tiles. With Allegro 4 I could create a color mask in a sub bitmap and use get_pixel to find where the mouse was. Is there a way to do this with Allegro 5?

Neil Roy
Member #2,229
April 2002
avatar

I have exactly what you need. I too used to use the colour map idea until I found this little gem, and it's easier than you may think.

tile_mx = (int)((((float)mouse_y + (float)scroll_y) / (float)TILE_Y) + (((float)mouse_x + (float)scroll_x) - ((float)MAPSIZE * (float)TILE_X/2)) / (float)TILE_X);
tile_my = (int)((((float)mouse_y + (float)scroll_y) / (float)TILE_Y) - (((float)mouse_x + (float)scroll_x) - ((float)MAPSIZE * (float)TILE_X/2)) / (float)TILE_X);

The variables are pretty self explanatory. TILE_X, TILE_Y for tile sizes, MAPSIZE for the size of the map, there is the mouse location in mouse_x and mouse_y. There is scroll_x and scroll_y which is the upper left corner of the visible map. I use this in an isometric map editor I programmed with a large scrolling map.

Note: This is for a large flat isometric map. If you have layers with things like hills, it gets more complex to detect which tile you are on. There are many ideas on how to do this, but not many people seem to want to share them. ;)

Chris Katko
Member #1,881
January 2002
avatar

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

dakatt
Member #10,695
February 2009

Thank you Neil, I did try using your code but I couldn't get it to work.

The last link you gave Chris is what I'm looking for but I don't know the Allegro 5 (or can remember the Allegro 4) code to implement it. I just remember the concept of creating a mouse mask with different colors, blitting it to a buffer/bitmap which wasn't seen and then using the get_pixel method to find out whether the current tile should be modified. Thanks again guys

Dizzy Egg
Member #10,824
March 2009
avatar

al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int y) ?? ;D

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Edgar Reynaldo
Member #8,592
May 2007
avatar

dakatt
Member #10,695
February 2009

Yes, possibly :/ Can Allegro 5 do something like this?

Neil Roy
Member #2,229
April 2002
avatar

Well, the code works, I use it in my Isometric editor. I pulled that straight out of it in fact.

I have some notes on this, let me pull them up and maybe they will help. It's been a while since I looked at them.

-------
isoX = map X coordinates
isoY = map Y coordinates
isoMapMaxY = How big is the map in Y direction
tileWidth = what is the width of the isometric map tile
tileHeight = what is the height of the isometric map tile

Lets assume that the whole map fits the screen for now.

screenX = screen x coordinate
screenY = screen y coordinate

Now, lets look at the code now with all this extra info.

From isometric coordinates to screen coordinates:
screenX = (isoX - isoY + isoMapMaxY) * (tileWidth / 2);
screenY = (isoX + isoY) * (tileHeight / 2);

From screen coordinates to isometric coordinates:
isoX = ( ((screenY + scrollY) / tileHeight) + ((screenX + scrollX) - (isoMapMaxY * tileWidth/2)) / tileWidth )
isoY = ( ((screenY + scrollY) / tileHeight) - ((screenX + scrollX) - (isoMapMaxY * tileWidth/2)) / tileWidth )

isoX = (screenY / 32) + (screenX - 320) / 64
isoY = (screenY / 32) - (screenX - 320) / 64
-------

Ariesnl
Member #2,902
November 2002
avatar

I always wanted to make an isometric game, problem is I could not draw a sprite if my life depended on it ::). and you never find enough graphics for an isometric game.
Top down graphics are much easier to get.

Perhaps one day we will find that the human factor is more complicated than space and time
(Jean luc Picard)

Chris Katko
Member #1,881
January 2002
avatar

Ariesnl said:

I always wanted to make an isometric game, problem is I could not draw a sprite if my life depended on it ::). and you never find enough graphics for an isometric game.
Top down graphics are much easier to get.

- Use placeholder graphics

- Learn to make isometric graphics even if you suck at it.

- Pay someone for ready-made licensed art (and optionally modify the art for your game using the art pack as a template for art-style)

- Pay someone to made new art. (If your game is worth playing, it's worth blowing a few hundred bucks or more on some artist to make it visually appealing.)

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Neil Roy
Member #2,229
April 2002
avatar

Here's some tiles I made myself, you're welcome to use them if you wish, at least to get you started. The roads are in the same style as SimCity2000, but they're not copied from that game, I made them myself from scratch (no copyright issues).

There's tutorials online, I suggest looking up tutorials on making tiles with Blender. I am not much of an artist either, but creating 3D renders is easier and perfect for isometric tiles. Another good program that helps create them easier is Inkscape, there are tutorials for it as well.

{"name":"611311","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/a\/3a6c816125706c8159fd3cb7fcbb72df.png","w":640,"h":256,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/a\/3a6c816125706c8159fd3cb7fcbb72df"}611311

I organized these tiles in a binary fashion. So the north corner is 1, the east corner is 2, the south corner is 4 and the west corner is 8. To get the tile number you want, just figure out which corners you wish to be raised, so if you want the north and east corner, that's tile #3 (1 + 2). The roads are organized in a similar fashion. I done it this way so that in my Isomed editor you can just draw the roads and tiles and it will use binary logic to select and combine tiles (I done something like this in my Deluxe Pacman 2 editor to draw as well).

This is an example of how these look. Believe it or not, I created these tiles just with Microsoft's Paint, that's it.

{"name":"611312","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/0\/30d213ee3764963ecda394a09d720c36.jpg","w":495,"h":269,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/0\/30d213ee3764963ecda394a09d720c36"}611312

dakatt
Member #10,695
February 2009

OK, I'll try and explain more clearly. I want to take what's on display (ie the buffer in allegro 4), draw a bitmap of the mouse mask over the top of (the copy of) the display and then use the mouse coordinates to check which color the mouse cursor is currently over. All of this should be invisible to the user. Here is my current code for this function :

#SelectExpand
1void CLayer::CheckMouse(int tile_xpos,int tile_ypos,int xt,int yt){ 2if(mouse_x>=tile_xpos && mouse_x<=tile_xpos+TILE_W && mouse_y>tile_ypos && mouse_y<tile_ypos+TILE_H){ 3 current_mx = tile_xpos; 4 current_my = tile_ypos; 5 6 current_xtile=xt; 7 current_ytile=yt; 8 9 //create image/copy of screen and overlay mouse mask 10 //use get_pixel() to find current color of mouse x/y 11 12 //finally increase/decrease the current_xtile/current_ytile depending 13 //on the color 14 15 over_tile=true; 16 17 } 18}

At present it takes the coords of the current tile, checks to see if the cursor is within its border and if it is assigns the current tiles array position to the current_ variables. Does anybody know how to go about this? thanks

Neil Roy
Member #2,229
April 2002
avatar

You're talking about a mousemap (search online for that term).

I used to use one with my program, this one to be exact (with the tiles I posted above if you want it)...

{"name":"611314","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a3043314ff5c121b96d07e5ad63cae05.png","w":640,"h":128,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a3043314ff5c121b96d07e5ad63cae05"}611314

It's a fairly simple technique, just figure out which tile you are clicking on, which tile number is at that location, then check the identical mousemap. You just check the colour at the location your mouse clicked on and go from there. If the colour is red, you clicked on a tile north of the position your mouse is on (actually, north-west, depending on how you draw them). If you clicked on cyan, you go one tile south, blue is north-west etc.

I have not bothered to try coding this with Allegro 5, though it should be simple. I used Allegro 4 for my Isometric project (it's an older one).

dakatt
Member #10,695
February 2009

Thanks again Neil. A mouse map is what I'm talking about, I've done it before with Allegro4 I just don't know what specific lib functions I used. Had I access to my old Isometric project I could probably take a stab at it since most variables and function names just seem to have the al_ prefix. Problem is I don't have the old code so I can't do that.

The concept is simple - make a bitmap (subbitmap? Idk), add to it a mouse map (again no clue on how to merge bitmaps), get colour from said bitmap. Maybe this allegro doesn't have the same functionality as the previous version although this stuff seems like it should be standard.

Neil Roy
Member #2,229
April 2002
avatar

The way I did it was I loaded two totally separate bitmaps, the main graphics and the mousemap (I provided some above). Once you know what tile you are in (just a general idea, the square area, not the isometric one), you then check which tile type if there then check the equivalent mousmap tile for the colour.

You just need an Allegro function where you can check the colour of a pixel on a bitmap. In this case, I have a 32bit PNG file for the mousemap.

I have not done this for Allegro 5 yet, but I would think you need to lock the bitmap for reading only, then call a function to read a pixel and check the colour. Should be pretty straight forward to be honest.

Go to: