CollisionRect and CollideImage - possible bug??

BlitzMax Forums/BlitzMax Programming/CollisionRect and CollideImage - possible bug??

GfK(Posted 2007) [#1]
[edit] Gah. I meant CollideRect! Must stop posting at 1am!

Hello.

First, sorry I can't post any code as its all kind of mashed up in the rest of my game code, so I'll just ask a quick question.

Basically I'm using CollideRect on my game front-end to handle option clicks. In the game I'm using CollideImage to check for mouse clicks on game graphics.

The trouble is, when I return to the front-end and begin using CollideRect again, it is adding to the collision layer the image I was using previously (a hexagonal shape).

I've written a little routine to take a 'screenshot' of my collision layer, created with CollideRect. You can see from the shot below that it is actually stamping down elongated hexagons. This is wrong. CollideRect should *always* draw rectangles, right?!



This is what the collision layer looks like, using the exact same code. Only difference is that CollideImage has *not* been used previously.




Amon(Posted 2007) [#2]
I don't know why that's happening but what I do with menu options is use the mouse position to get the location of the graphic I want checked.

I do the following.

global MyImageXLoc:int = 100
global MyImageYLoc:int = 100

if mousex() - MyImageXloc > 0 and Mousex() - MyImageXloc < Imagewidth(MyImage)
    if mousey() - MyImageYLoc > 0 and Mousey() - MyImageYloc < ImageHeight(MyImage)
        If mousehit(Mouse_Left)
       'DoStuff
        endif
     endif
endif


You probably already new this. I do it this way because then I don't have to use Collision commands.


skidracer(Posted 2007) [#3]
Can you try calling ResetCollisions in your front end init.

Hmm, some sort of rotation / clip region might be causing the error as illustrated, try also a SetRotation 0 also before calling CollideImage.


GfK(Posted 2007) [#4]
Hi skid - I'm doing all that.

I've jammed all sorts in to try to fix this, and nothing has worked. The top part of my function (before I start creating the collision layer) looks like the code below.

The For/Next loop is in there because it fixes the problem, crude as it is. Seems that calling CollideRect a few times eventually rectifies the problem. I don't know why.

Oh - I also tried manually calling GCCollect here too - didn't work.

 	SetScale 1,1
	SetRotation 0
	SetBlend SOLIDBLEND
	SetAlpha 1
	savePrefs()
	FlushMouse()
	Local x:Int
	Local y:Int
	Local w:Int
	Local h:Int
	ResetCollisions
	For n = 1 To 50
		CollideRect -2,-2,1,1,0,1
	Next



Grey Alien(Posted 2007) [#5]
This is pretty nuts, hope you find out the answer!


GfK(Posted 2007) [#6]
I wonder if CollideImage and CollideRect use the same code only with a different mask? The image (the hexagon) has actually been freed, but it appears to me that for some reason (and assuming the above to be correct) that the mask used by CollideImage/CollideRect is not being reset.

Does this make any sense??


Damien Sturdy(Posted 2007) [#7]
Those are weird looking rects! This explains a few things I was having probs with a few months back, too! :O


Dreamora(Posted 2007) [#8]
what are you exactly expecting from above code?
You create colliderects fully outside the screen there which collides with anything and writes to layer 1.
Perhaps that causes some problems.


GfK(Posted 2007) [#9]
what are you exactly expecting from above code?
Um, I'm expecting CollideRect to create a collideable rectangle, not a collideable elongated hexagon!

You create colliderects fully outside the screen there which collides with anything and writes to layer 1.
Perhaps that causes some problems.
Read the entire first post.

Creating those colliderects off-screen is SOLVING the problem, not causing it.

Is it significant that they're off screen? No. I put them off screen so they can't be interacted with.


Dreamora(Posted 2007) [#10]
Not drawing them would at all would do the same, just that the collision system does not have to drop the calls first, right?

but none the less. Strange error, never had that so far.

On the other side, I strictly seperate the used write layers. There are static layers (for menu and other things that will never move), those are never cleared nor redrawn after creation, this reduces the collision test time dramatically.
Dynamic objects only read collisions against that layers


on the other side, there are dynamic layers which are cleared after any position update.
As there are many different images used on dynamic, I assume I would have run into this problem at some point, because in some cases (large images) I do rect test before doing image tests to see if there is a potential collision at all. But so far, all seemed to work as it was intend to, at least it seemed to (haven't seen any "missassumptions" of a degree of above image so it would have been easy to spot as some kind of an error)


How does your "draw the collision layer" function look like?
Do you simply move a 1,1 collisionrect from top left to bottom right or a 1,1 pixel large image to do it with image vs rect collision?


tonyg(Posted 2007) [#11]
I'm probably missing something but is this close to what you're doing :

?
If not, what are you doing differently?


GfK(Posted 2007) [#12]
YES! Managed to reproduce this behaviour in stand-alone code. I'll post it up in a few minutes. There's certainly an issue here.


GfK(Posted 2007) [#13]
OK, try this - I know its very scruffy but it demonstrates the problem.

You can find ship.png in "C:\Program Files\BlitzMax\samples\mak".

Couple of pointers. First, I've used a small graphics window simply to speed up the collision layer rendering function. It does the same in any resolution, though.

It makes no difference what PNG image I use. It also makes no difference whether I just use one image, or a frame from an AnimImage.

Also, it doesn't even matter if I use img = Null before using CollideRect. CollideRect still draws ships where it should draw rectangles.

Finally, I'm returning the CollideRect result into an array basically because the code was ripped straight from the collision code in my game (where I need to check for multiple collisions). I realise it isn't necessary in this circumstance, though.

The code will first create a collision layer with the ship, then clear it and create a new layer with CollideRect. At the end it saves an image of the collision layer. If you look at this you should see several yellow rectangles on a green background. I see several yellow ships.

Graphics 320,240

img:timage = LoadImage("ship.png")

'create collision layer a few times
SetScale 0.3,0.3

ResetCollisions
For X = 0 To 250 Step 20
	For Y = 0 To 200 Step 20
		CollideImage img,X,Y,0,0,1
	Next
Next

'build a new layer with CollideRect
ResetCollisions
For X = 0 To 250 Step 50
	CollideRect X,120,64,64,0,1
Next

rendercollisionlayer()
End

Function renderCollisionLayer()
	SetBlend SOLIDBLEND
	SetAlpha 1
	SetScale 1,1
	Cls
	For X = 0 To GraphicsWidth()
		For y = 0 To GraphicsHeight()
			Local mArray:Object[] = CollideRect(x,y,1,1,1,0)
			If mArray.length > 0
				SetColor 255,255,0
			Else
				SetColor 40,128,40
			EndIf
			Plot x,y
		Next
	Next
	img:TPixmap = GrabPixmap(0,0,GraphicsWidth(),GraphicsHeight())
	SavePixmapPNG img,"collisionlayer.png"
End Function



GfK(Posted 2007) [#14]
OK, this is something to do with ResetCollisions. If I comment it out (the second one in the code above), then I get rectangles, as expected.


Grey Alien(Posted 2007) [#15]
Thank God I wrote my own rect collision code for Oz and HB!


Dreamora(Posted 2007) [#16]
ok, same here.

Was this bug "omnipresent" or introduced in one of the latest changes? (its not DX module replacement based :) )

Perhaps bound to
1.19 Release: Fixed collision bug with non alpha/masked images



skidracer(Posted 2007) [#17]
Thanks GfK for all the hard work tracking this one down, please syncmods for fix.


GfK(Posted 2007) [#18]
[edit] never mind. posted same time as skidracer :D


GfK(Posted 2007) [#19]
Thanks GfK for all the hard work tracking this one down, please syncmods for fix.
Great stuff! Works perfectly now. Thanks! :)


Dreamora(Posted 2007) [#20]
Thanks skid


Grey Alien(Posted 2007) [#21]
Top hunting and fixing guys!