Check collision for image in the same layer??

BlitzMax Forums/BlitzMax Programming/Check collision for image in the same layer??

RepeatUntil(Posted 2005) [#1]
It seems to be impossible to check collisions between images belonging to the same layer. Does somebody knows a solution?

For details:
I want to use the CollideImage() function, and I use for that the image layers. For example: background=0, monsters=1, pickups=2, player=3 (the bitmasks for these would be 1,2,4,8 respectively).

So first I do a call to collideImage, writing to the specific layers:
CollideImage(image1,x1,y1,0,0,layerPlayer)

Then I test if my image collided with another image.
If CollideImage(image2,x2,y2,0,layerPlayer,0)

But if I want to check if a player collided with another player, then I will test this with
If CollideImage(imagePlayer,x,y,0,layerPlayer,0)

And this will always return true since imagePlayer belongs to the layer of players, so the image is always colliding with itself!! Is it not possible to check collision for images in the same layer??


Diablo(Posted 2005) [#2]
I dont think what your trying todo will ever work - If you think CollideImage works like collisions in Blitz3D. The reason is because I dont think it treats the images as spreate objects meaning that it can't check if the image is the same as the one being passed to it. You should look at the other collision functions like ImagesCollide & ImagesCollide2. Of course, I don't think it would be to hard to make a little function+type thing that would help you out.


skidracer(Posted 2005) [#3]
You will need to collect player to player collisions as you write to the playerlayer:

hitplayers=CollideImage(image1,x1,y1,0,layerPlayer,layerPlayer)

As CollideImage first tests for any read collisions b4 writing to the target layers.

This will only return a collision with the players already drawn so you want to be using some sort of object pointers to set a collided field like so:

For player=EachIn playerlist
	Local hitplayers:Object[]=CollideImage(x,y,frame,playerlayer,playerlayer,player)
	If hitplayers
		player.collided=True
		For hitplayer=EachIn hitplayers
			hitplayer.collided=True
		Next
	EndIf
Next



RepeatUntil(Posted 2005) [#4]
Thanks, skid! Finally I have created a little function that does the hard part, using your idea.
This function just use CollideImage, but returns an array *without* the object we are testing. It seems much more logical to do things like this. Maybe something similar could be implemented directly in collideImage???

Anyway, I use it like this:
CollideImage2(x,y,frame,0,playerLayer,player) (collideImage would work as well)
Then, later on, to check collisions:
if collideImage2(x, y, frame, playerLayer, 0, null, self) then blah

Here is it:
' Function checking the collision, but will remove the testedObject from the list of collision. This allows
' collision for objects of the same layer.
Function CollideImage2:Object[](image:TImage, x, y, frame, collideMask%, writeMask%,  id:Object, testedObject:Object=Null)
	Local collidedObjects:Object[] = CollideImage(image, x, y, frame, collideMask, writeMask, id)
	' Test if the object is present in the collision list
	Local testedObjectPresent:Byte = False
	For Local collidedObject:Object = EachIn collidedObjects
		If collidedObject = testedObject Then testedObjectPresent = True
	Next
	' Create the new array we will return
	Local dim
	If testedObjectPresent Then dim = collidedObjects.length - 1 Else dim = collidedObjects.length
	Local collidedObjectsReturned:Object[dim]
	' Remove the object from the collision list if it's present
	Local i = 0
	For Local collidedObject:Object = EachIn collidedObjects
		If collidedObject <> testedObject Then 
			collidedObjectsReturned[i] = collidedObject
			i:+1
		EndIf
	Next
	Return collidedObjectsReturned
End Function