Best way to detect a side collision

BlitzMax Forums/BlitzMax Programming/Best way to detect a side collision

Hey,

I've got a game that requires me to know what side an object was hit on. In order to deflect that object in the right direction.

For example, imagine a cube, you have a ball traveling upward, and you make calls to watch for a collision. Once a collision is made you make changes so the ball travels downward now.

What if we hit that cube on the right side? You of course would want the ball to change its direction from left to right, and not just downward.

So how do I detect the side of a collision?

My idea would be to do a Rects collide check against the object (one for object A. and check on four rects, one for each side)

But in my cases, this leaves odd behavior and bugs.

Any ideas?

PS. my object is a rounded rectangle NOT a square

SuperStrict

Graphics 640 , 480 , 0 , 0

Global ballx:Int = MouseX() 
Global bally:Int = MouseY() 
SetBlend alphablend

Global sc:Float[] = [100.0 , 100.0 , 100.0 , 100.0]
Global leftZone:Float[] = [90.0 , 90.0 , 20.0 , 120.0]
Global rightZone:Float[] = [190.0 , 90.0 , 20.0 , 120.0]
Global topZone:Float[] = [90.0 , 90.0 , 120.0 , 20.0]
Global bottomZone:Float[] = [90.0 , 190.0 , 120.0 , 20.0]

Const CT_NONE:Int = 0
Const CT_LEFT:Int = 1
Const CT_TOP:Int = 2
Const CT_RIGHT:Int = 4
Const CT_BOTTOM:Int = 8

Global collisionFlags:Int = CT_NONE

Global oldOriginX:Float = 0.0
Global oldOriginY:Float = 0.0



While Not KeyDown(KEY_ESCAPE)

Cls

	Local mx:Int = MouseX() 
	Local my:Int = MouseY() 
	Local ballRect:Float[] = [mx+0.0 , my+0.0 , 10.0 , 10.0]
	collisionFlags = CT_NONE
	'check collisions
	If rectsOverlap( sc , ballRect ) Then
		If rectsOverlap( leftZone, ballRect ) Then
			collisionFlags = collisionFlags | CT_LEFT
		EndIf
		If rectsOverlap( topZone, ballRect ) Then
			collisionFlags = collisionFlags | CT_TOP
		EndIf
		If rectsOverlap( rightZone, ballRect ) Then
			collisionFlags = collisionFlags | CT_RIGHT
		EndIf
		If rectsOverlap( bottomZone, ballRect ) Then
			collisionFlags = collisionFlags | CT_BOTTOM
		EndIf
	EndIf

	'draw the square
	SetColor(0,255,0)
	DrawRect( sc[0] , sc[1] , sc[2] , sc[3] ) 
	
	'draw the zones

	If (collisionFlags & CT_LEFT) Then
		SetAlpha(1)
		SetColor(255 , 255 , 255) 
		DrawText("LEFT", 0,0)
		SetAlpha(0.75)
	Else
		SetAlpha(0.25)
	EndIf
	
	SetColor(255 , 0 , 255)
	DrawRect(leftZone[0] , leftZone[1] , leftZone[2] , leftZone[3])
	
	
	If (collisionFlags & CT_RIGHT) Then
		SetAlpha(1)
		SetColor(255 , 255 , 255) 
		DrawText("RIGHT", 0,18)
		SetAlpha(0.75)
	Else
		SetAlpha(0.25)
	EndIf
	
	SetColor(155 , 0 , 255)
	DrawRect(rightZone[0] , rightZone[1] , rightZone[2] , rightZone[3])
	
	
	If (collisionFlags & CT_TOP) Then
		SetAlpha(1)
		SetColor(255 , 255 , 255) 
		DrawText("TOP", 0,36)
		SetAlpha(0.75)
	Else
		SetAlpha(0.25)
	EndIf
	
	SetColor(0 , 255 , 155)
	DrawRect(topZone[0] , topZone[1] , topZone[2] , topZone[3])
	
	
	If (collisionFlags & CT_BOTTOM) Then
		SetAlpha(1)
		SetColor(255 , 255 , 255) 
		DrawText("BOTTOM", 0,54)
		SetAlpha(0.75)
	Else
		SetAlpha(0.25)
	EndIf
	
	SetColor(255 , 255 , 0)
	DrawRect(bottomZone[0] , bottomZone[1] , bottomZone[2] , bottomZone[3])
	
	SetAlpha(1) 


	'draw the ball
	SetColor(255 , 255 , 255) 
	DrawOval(mx , my , ballRect[2], ballRect[3]) 

Flip
	
Wend
End

Function rectsOverlap:Int( rect1:Float[] Var , rect2:Float[] Var  )
	If rect1[0]> (rect2[0] + rect2[2]) Or (rect1[0] + rect1[2]) < rect2[0] Then Return False
	If rect1[1] > (rect2[1] + rect2[3]) Or (rect1[1] + rect1[3]) < rect2[1] Then Return False
	Return True 
End Function


Any use?

That helps. It's a rects collide check for each side, similar to what i used before, I'll see if i can work it, as I can't seem to come up with any other methods.

Thanks