Clickable Regions

Blitz3D Forums/Blitz3D Beginners Area/Clickable Regions

Basil(Posted 2003) [#1]
Hi guys, any comments would be helpful.

I have a screen carved up into different regions (279 of them). Visually a bit like Minesweeper. To determine which region the user has clicked in, I have always used groups of Ifs eg

If MouseX < 40 and MouseX > 20 then
If MouseY < 50 and MouseY > 30 then
Region = 1
Endif
If MouseY < 80 and MouseY > 60 then
Region = 2
Endif
Endif
If MouseX < 70 and MouseX > 50 then
If MouseY < 50 and MouseY > 30 then
Region = 3
Endif
If MouseY < 80 and MouseY > 60 then
Region = 4
Endif
Endif

...etc

Very laborious and ugly with 279 regions.

Is there a better way?

I could re-write it with Select / Case but that would be pretty much the same. (I also remember hearing somewhere that most compilers implement Cases as nested Ifs anyway.)

Cheers

Basil


skn3(Posted 2003) [#2]
Type region
	Field id
	Field x,y,width,height
End Type

;make some regions
r.region = New region
r\id=1
r\x=23
r\y=50
r\width=100
r\height=66

r.region = New region
r\id=2
r\x=200
r\y=400
r\width=30
r\height=60

r.region = New region
r\id=3
r\x=130
r\y=100
r\width=300
r\height=200

r.region = New region
r\id=4
r\x=500
r\y=250
r\width=90
r\height=90

;example loop
Graphics 640,480,0,2
SetBuffer BackBuffer()
Repeat
	Cls
	;draw the regions just for demo purposes
	For r.region = Each region
		Rect r\x,r\y,r\width,r\height,0
	Next
	
	Text 5,5,"region="+getregion()
	
	Flip
Until KeyDown(1)

Function getregion()
	For r.region = Each region
		If MouseX() >= r\x
			If MouseY() >= r\y
				If MouseX() <= r\x+r\width
					If MouseY() <= r\y+r\height
						Return r\id
					End If
				End If
			End If
		End If
	Next
	Return False
End Function



Elf(Posted 2003) [#3]
If the regions are equally spaced and sized, a quick bit of maths could do the job.

E.g. if the regions are 50 pixels wide each and start 100 pixels from the left of the screen, you can get one by taking the offset from the mouse X position, then dividing the answer by the width of each region:

Region = ( MouseX() - 100 ) / 50

This gives you the position "across".

I assume the regions are set up in a grid, minesweeper style, so we get the Y position and multiply by the number of regions in each row- e.g. if there were 10 regions in each row, and the rows were 50 pixels high:

Region = Region + ( ( MouseY() - 100 ) / 50 ) * 10

Note this is theory, not ready-to-run code!


GfK(Posted 2003) [#4]
This will help:
http://www.blitzbasic.com/codearcs/codearcs.php?code=597


Basil(Posted 2003) [#5]
Thanks chaps.

A couple of new ways of looking at it (I sometimes get fixated on a single method).

Though, since I've written the code with loads of IFs, I'll stick with it - it runs quickly enough.

Next time, however, I think I'll try Elf's method.

Thanks again

Basil