Qbasicnews.com

Full Version: Hello, Help is needed with isometric map engine.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi, I'm making a game called Tycoom(see in the projects...)

Anyway. I encountered a problem I'm not sure how to solve. The problem is with the mouse. How to get on what tile mouse pointer is?

The thing what makes it difficult is that:
X and Y rows of the map progress diagonally on the screen.
Tile isn't square, but a rhomb what is placed on the screen under angle.

To see the code download the prog. There is exe file, but also source what I tryed to comment a bit. Also make sure that three bmp files are in the same folders(included)

Also there is small BMP file called Exampl.bmp -it shows how rows goes... just check it out you'll understand.

I'd be really happy if someone would help me out. Of course I know it IS pretty diffivult... At least for me :oops:

http://www.hot.ee/wizgui/BIN.exe
Here is sum niffty code i used in my now obsolete Hobbit 2D Map Engine stuff

Code:
DEFINT A-Z

DECLARE Sub MouseTile (X, Y, TileSizeX, TileSizeY)



SUB MouseTile (X, Y, TileSizeX, TileSizeY, SpaceX, SpaceY)

'Backup old mouse position to emulate BYVAL
ox% = (SpaceX - X)
oy% = (SpaceY - Y)

x = ox% \ (xRes-SpaceX) * TileSizeX     'Notice the integer division...
y = oy% \ (yRes-SpaceY) * TileSizeY     'ditto

END SUB

You'll have to manually change the x & y res variables

You may also have to subtract the value at which the map Editor starts

Code:
-------------------------------------------------------------------
-        File Edit ...                                                         -
-------------------------------------------------------------------
             |
             |
             |
             |
             |
             |
             |
             |
             |
             |
             |
             |
-------------------------------------------------------------------
     ^Tool bar            ^ Map Editor Section

Ex:

Code:
'First we assume that the menu takes up 20px, and the Tool Bar
'takes 50px

CALL MouseTile (MouseX, MouseY, 16, 16, 50, 20)

Alex~
Quote:Here is sum niffty code i used in my now obsolete Hobbit 2D Map Engine stuff

Code:
DEFINT A-Z

DECLARE Sub MouseTile (X, Y, TileSizeX, TileSizeY)



SUB MouseTile (X, Y, TileSizeX, TileSizeY, SpaceX, SpaceY)

'Backup old mouse position to emulate BYVAL
ox% = (SpaceX - X)
oy% = (SpaceY - Y)

x = ox% \ (xRes-SpaceX) * TileSizeX     'Notice the integer division...
y = oy% \ (yRes-SpaceY) * TileSizeY     'ditto

END SUB

You'll have to manually change the x & y res variables

You may also have to subtract the value at which the map Editor starts

Code:
-------------------------------------------------------------------
-        File Edit ...                                                         -
-------------------------------------------------------------------
             |
             |
             |
             |
             |
             |
             |
             |
             |
             |
             |
             |
-------------------------------------------------------------------
     ^Tool bar            ^ Map Editor Section

Ex:

Code:
'First we assume that the menu takes up 20px, and the Tool Bar
'takes 50px

CALL MouseTile (MouseX, MouseY, 16, 16, 50, 20)

Alex~

Alex It won't work with my mapengine, because tiles aren't squares, but rhombs. Check out the fail I posted to see.
Ok....if its a tilted square...you'll ahve to increment the x value in comparision to the y

lets say every y, the 2 is added to the x (you'll have to get into slope for the actual angle)

So, revised:


Code:
DECLARE Sub MouseTile (X, Y, TileSizeX, TileSizeY)

CONST IncremPxl = 1

SUB MouseTile (X, Y, TileSizeX, TileSizeY, SpaceX, SpaceY)

'Backup old mouse position to emulate BYVAL
ox% = (X - SpaceX)
oy% = (Y - SpaceY)

x = ox% \ (xRes-SpaceX) * TileSizeX     'Notice the integer division...
y = oy% \ (yRes-SpaceY) * TileSizeY     'ditto

incremx = (y * IncremPxl) - IncremPxl
x = x + incremx

END SUB

Im nost sure of teh angle again, so change the IncremPxl to the specific slope...

Otherwise, i think I saw a VB program that used Isometric angled tiles....i'll c if i can dig it up (but i don't think it was open source..)

Alex~
Hmm.. thought I'd take a crack or at least help you out with what little I know. This should point you in the right direction if it doesn't give you an answer. :wink:

It's been a few years since I've had any math classes, but I believe I have an idea that'll work. Basically, with a square tile engine we generate the tile coords by testing the mouse's x and y against four equations that generate a square on the screen, two horiz. lines and two vert. lines (ex: y = 5; x = 3). Well, a regular rhombus such as you're using is made up of two equations on a graph using absolute values. When graphed, an absolute value function such as y = |x| (the | | stand for absolute values, ABS() function in QB) will make a V. Your rhombus is one of these with another flipped on top of it and offset by a y value equal to the height of the rhombus. Since we have two equations, we know that for a point to be on or in the borders of the rhombus, the x value when plugged into them should generate a y value that is greater than or equal to the first equation and less than or equal to the second (upside down) one. This seems confusing as I'm typing it even to me, so I'm posting code to a test prog I made. It draws a rhombus on a grid the same dimensions (64*31) as yours for the game.

Code:
SCREEN 13
ox = 160
oy = 150

COLOR 15
LINE (ox, oy - 50)-(ox, oy + 50)
LINE (ox - 100, oy)-(ox + 100, oy)
LINE (ox - 5, oy - 31)-(ox + 5, oy - 31), 4

FOR x = -31 TO 32
y = .5 * ABS(x)
PSET (ox + x, oy - y), 14
y = -(.5 * ABS(x)) + 31
PSET (ox + x, oy - y), 14
NEXT

PRINT "2 Equations make this rhombus:"
PRINT "   y = .5 * ABS(x)"
PRINT "   y = -(.5 * ABS(x)) + 31": PRINT ""

DO
  LOCATE 5, 1
  INPUT "Enter a test x coord: ", tx
  INPUT "Enter a test y coord: ", ty
  PRINT ""
  PSET (ox + tx, oy - ty), 13
  IF ty >= .5 * ABS(tx) AND ty <= -(.5 * ABS(tx)) + 31 THEN PRINT "It's in the Rhombus." ELSE PRINT "It's not in the Rhombus."
  PRINT "(Push ESC to quit, any other to retest.)"
  SLEEP
  a$ = INKEY$
  FOR y = 5 TO 9: LOCATE y, 1: PRINT SPACE$(80): NEXT
LOOP UNTIL a$ = CHR$(27)

Run it and you can see my rhombus is a little sloppy looking, but this should work just fine and by looking at the loop there you can see how I tested the values. I would recommend changing the y of your rhombi to an even number if possible, btw. It might make things a little easier (might not = P).

Anyways, to figure out what tile the mouse is over, you have to approach this a little differently. Basically, you need to figure out which two equations the points do fit into, not just whether or not they do as in my prog. At the moment, I can't think of what to do, but I'm going to head to the bathroom with a pad and a pen and see what I can hash up. If I don't come back, it was either a really horrible bathroom break or I just couldn't think of a solution. (Hah, like that would ever happen..)

(On a side note, I'd recommend having the map scroll diagonally when the pointer is in the corners.)
Ok.. well, not a whole of anything useful came to me on the toilet and I'm about to head out to pack and move stuff to my new apartment, but maybe this will cause something to click in your brain. Imagine "zooming" the map out to where you could see the entire thing. This would take a screen size of 4096x2048 (with tiles that are 64*32... with 64*31 it'd be 4096*1984). The map itself would be one fat ol' rhombus with these equations (based on a large screen where we want the origin to be the bottom left corner and as in QB the Y values are reversed):
Code:
y = .5 * ABS(x-2048)
y = -(.5 * ABS(x-2048)) - 2048
The -2048's adjust the equation to fit the whole rhombus in the first quadrant (with positive x and y values). Now, envision this huge rhombus on a grid (I so wish I could post a scan of my pad.. heh) and it is broken up into tiles just like the display. Each mini rhombus is going to have its own two sets of equations. Let's look at the equations for (1,1) (2,2) (2,1) and (1,2):
Code:
/\
    /  \
   /2,1 \
  /\    /\
/  \  /  \
/1,1 \/2,2 \
\    /\    /
\  /  \  /
  \/ 1,2\/
   \    /
    \  /
     \/

(1,1): y = .5 * ABS(x - 32) + 1008
       y = -(.5 * ABS(x - 32)) + 1040
(2,2): y = .5 * ABS(x - 96) + 1008
       y = -(.5 * ABS(x - 96)) + 1040
(2,1): y = .5 * ABS(x - 64) + 1024
       y = -(.5 * ABS(x - 64)) + 1056
(1,2): y = .5 * ABS(x - 64) + 992
       y = -(.5 * ABS(x - 64)) + 1024
With these four sets of equations, we can see how the equations change for the tile x/y's as they move right/left or up/down. I know this is useful, but I have yet to figure out why. :wink: I'm gonna leave now and ponder it while I move or leave you hanging if you get on before I finish this or let someone else finish it all up. (Lots of options..) But, you are going to want to convert your mouse x/y coords into what it would be on the grid of 4096*2048. This is easily done using your offsets for drawing the map and a little multiplication. Once you have those, you have to figure out which sets of equations the darn things fit into. If I had a little more time I could write up another prog that would do that based on knowing the increments in the ABS function and y intercepts. But, I don't. Later. Big Grin
Hi,

Tnx Ryan!

This is lot of information to me to work throw. Your idea seems interesting, but little confusing(sorry, for me, because I'm not native english speaker... But eventually I'll work it through)

I also came up with small idea of my own, though I don't know would it work or not.

I thought about making a function that would calculate Mouse X and Y point distance not from edges of the screen, but from two edges of the map. And then I would detect on what tile mouse is just like with any ordinary system. I have to still think about it.

What you think would it work? I still have to figure out how to code it, but oh well... Challange is the best part of programming :king:
hehe Yeah, for me I program for the challenge of figuring stuff out. That's why I rarely ever finish anything.. at all. I can't think of a single thing I've finished though I have tried just about every type of game to figure out the code.

Anyways, an idea hit me while I was in the shower that if it works (which I think it should, though maybe not that fast) would let you forget about the rhombus equations. Well, it helps to know the math behind them, but there might be an easier way. It would still involve thinking about the map as being on a large grid and converting the mouse's x/y coords into coords on that large grid. This is easily done like so:
Code:
gridx = Future.MouseX + map's x tile offset * tile's x width
gridy = grid height - (Future.MouseY + map's y tile offset * tile's y height)


Ugh.. I just deleted what I had posted up to this. That bit of code just up above might be useful, but I realized as I was doing this that the bit of code would fall apart for certain areas of the rhombus. Well, at least it seems it would. It really is too late, but tomorrow if you haven't figured it out I'm going to try this idea in your prog or at least a test one. I still think it has potential. :wink:

(Basically, the idea was to sort through the grid like I would with a normal tile engine, you just have different equations to check against. So instead of seeing of my x value was between 5 and 10, I'd loop through the tilted line equations which for the x-axis of a rhombus map of 64 wide *32 high tiles would be y = .5x + MapSize/2 * 32 and for the y-axis would be y = (-.5x) + MapSize/2 * 32. Eventually you should end up with the x/y you want, but I need to tweak/test it out. We'll see...)