Making mouse-detectable zones

Blitz3D Forums/Blitz3D Beginners Area/Making mouse-detectable zones

XE800(Posted 2005) [#1]
Hi. I'm trying to make a map editor for an isometric RPG, and need to know the most effecient way of having the mouse interact with the map fields.

Currently I use this:

If MouseDown(1)=True And MouseX()>383 And MouseX()<415 And MouseY()>349 And MouseY()<381 Then Bonx=0 : Bony=0 : AddTile()

The visible part of the map is 12x12 blocks, so I need to make 143 more lines in the same vein. Something tells me there's a more rational way of doing this? Any input appreciated.

XE


LineOf7s(Posted 2005) [#2]
Why yes, there is:

http://www.blitzbasic.com/codearcs/codearcs.php?code=597


Ice9(Posted 2005) [#3]
Try Mappy. You can get it here I think.

http://www.tilemap.co.uk/

Look below in the mappy playback libraries.
There is ready to use code for blitz


XE800(Posted 2005) [#4]
Thanks, both of you. "Zones.bb" made life a lot easier. I also realized I could save the actual zone data in a seperate file, so my source got really trimmed down.

Mappy doesn't like my gfx, it seems. Kept crashing me to desktop :/ The error msg seemed somewhat generic, so not sure what caused it. Probably need to check the docs. But doesn't really matter, I'm very happy with my own editor now that I halved the source :)

XE


octothorpe(Posted 2005) [#5]
If your tiles are arranged in a grid and won't be moving around or changing shape along the X and Y axis, you should be able to determine which tile was clicked on by simply dividing by the size of the tiles (and acounting for the map offset).
; 2d example
const map_origin_x = 383, map_origin_y = 389
const map_tile_width = 32, map_tile_height = 32
;;;
tile_x = floor((mousex()-map_origin_x) / map_tile_width)
tile_y = floor((mousey()-map_origin_y) / map_tile_height)
; 3d example
const map_origin_x = 0, map_origin_y = 0
const map_tile_width = 32, map_tile_height = 32
entitypickmode(map_entity, 2) ; 2=polygon
;;;
mouseover_entity = camerapick(global_camera, mousex(), mousey())
if mouseover_entity = map_entity then
	tile_x = floor((pickedx()-map_origin_x) / map_tile_width)
	tile_y = floor((pickedy()-map_origin_y) / map_tile_height)
endif



XE800(Posted 2005) [#6]
I save the zone data like this:

Function SaveZones()
fo=WriteFile("Zones.dat")
For z=1 To 181
WriteInt(fo,ZoneProperty(z,1))
WriteInt(fo,ZoneProperty(z,2))
WriteInt(fo,ZoneProperty(z,3))
WriteInt(fo,ZoneProperty(z,4))
Next
CloseFile(fo)
End Function

But when using THIS to load:

Function LoadZones()
fi=ReadFile("Zones.dat")
For z=1 To 181
ZoneProperty(z,1)=ReadInt(fi)
ZoneProperty(z,1)=ReadInt(fi)
ZoneProperty(z,1)=ReadInt(fi)
ZoneProperty(z,1)=ReadInt(fi)
Next
CloseFile(fi)
End Function

... a Blitz alert-box shows up with the msg " Expecting ')' "

Why is this? I can't see any missing ')' anywhere :/ When removing the LoadZones function from the code, I get no alert.


octothorpe(Posted 2005) [#7]
ZoneProperty() is a function, and as such, you cannot treat it as an lvalue (meaning you can't assign to it with "="). I think you want to use the CreateZone() function when loading information from a file.

Out of curiousity, why can't an isometric tile-based RPG use the division solution I outlined above? It would be a substantially simpler approach if it could be made to work for you.


XE800(Posted 2005) [#8]
Oh yeah. First time I use a library, so I totally forgot that in Zones.bb it is a function. I treated it as a normal array.

I changed the names in the LoadZones function to ZoneProperty1(z), ZoneProperty2(z) etc. and now the values are loaded without problem.

But since it seems saving ZoneProperty(z,x) worked well, I will leave that one as it is.

Thx for your help!


XE800(Posted 2005) [#9]
"Out of curiousity, why can't an isometric tile-based RPG use the division solution I outlined above? It would be a substantially simpler approach if it could be made to work for you"

I tried it, but I guess it doesn't work well in a diamond shaped map. Instead of reading from the top and to the left, it read from the top and straight down. What was originally 1,1 became 0,0 and what was 2,2 became 0,1 :) And if I moved pointer to the left, I would soon get negatives.

I will investigate it further tomorrow though, as it would be great to get something like this working.

XE


octothorpe(Posted 2005) [#10]
It'll work, you just need slightly more complicated math. I'm using the same approach with the hexagon tiles in my game.

For a diamond-shaped map, you'll need to take into account both the X and Y position of the mouse when determining each of tile_x and tile_y. Something like this should work for you:
Const map_tile_offset_x = 32, map_tile_offset_y = 16
x_off# = MouseX() - map_origin_x
y_off# = MouseY() - map_origin_y
tile_x = Floor(x_off/map_tile_offset_x + y_off/map_tile_offset_y)
tile_y = Floor(y_off/map_tile_offset_y - x_off/map_tile_offset_x)
You'll also need to add 1 to both tile coordinates if your map originates at (1,1) instead of (0,0).