Rectangular and Circular Collision Detection

Level:
Level3

Games aren't much fun without collisions.. I mean, really, would you play Mortal Kombat if there were no contact, no blood? It'd just be some sort of friendly martial-arts ballet!

Basic collision detection techniques should be sufficient for most games. Side scrollers, puzzle games, RPGs, and many others can get by with rectangular detection. Shooters and any sort of space game would likely be better off with circular detection. You'll see that these techniques are quite rudimentary.

If you would like to follow along feel free to download the sample source code for this tutorial. 

Let me introduce you to my friend, the IntersectRect API call, and his buddy, the RECT type.

Type RECT
   Left As Long
   Top As Long
   Right As Long
   Bottom As Long
End Type
   
Declare Function IntersectRect Lib "user32" Alias "IntersectRect" _
   (lpDestRect As RECT, lpSrc1Rect As RECT, lpSrc2Rect As RECT) As Long

The IntersectRect function accepts three rectangles as arguments. It checks for intersection between the 2nd and 3rd arguments and places the resultant intersection rectangle in the first argument. Also, the function itself returns a value of 1 if there is an intersection, and a value of 0 if there is no intersection.

Obviously you could do these things manually with a number of If statements, but why bother? The IntersectRect API is simple to use, and fast. Watch:

mblnCollision = IntersectRect(udtTempRect, udtRect1, udtRect2)

This statement will check for intersection between udtRect1 and udtRect2 and assign the intersecting area to the rectangle udtTempRect. Also, if there IS an intersection, it will assign the value of True to the boolean mblnCollision. We can then take action based on the value of this boolean in other areas of the code.

Circular collision detection doesn't come with its own API call, so I've made my own function to speed things up a tad.

Private Function GetDist(intX1 As Single, intY1 As Single, intX2 As Single, _ 
   intY2 As Single) As Single
   
   ' DaB - Don't use ^2 it's really slow.
   GetDist = Sqr((intX1 - intX2) * (intX1 - intX2) + _
      (intY1 - intY2) * (intY1 - intY2))   
End Function

This will return the distance between any two points in an X,Y plane. To find out how far away two circles are, pass the coordinates of their center points. Then subtract the radii of the two circles, and viola! You have the distance between the circles!

 mblnCollision = (GetDist(msngCircle1X, msngCircle1Y, msngCircle2X, _
   msngCircle2Y) <= RADIUS1 + RADIUS2)
   
'Or do it "inline in one line" if you need speed (and avoid the Sqr and ^2 operators)
mblnCollision = ((msngCircle1X-msngCircle2X)*(msngCircle1X-msngCircle2X) + _
   (msngCircle1Y-msngCircle2Y)*(msngCircle1Y-msngCircle2Y)) <= _
   (RADIUS1+RADIUS2)*(RADIUS1+RADIUS2)

Analogous to the rectangle code shown above, this code will assign True or False to the boolean depending on the outcome of the collision detection attempt. If the distance between the circles' centers is less than the sum of the radii, then they've collided. It's that easy.

Have a look at this sample source code which demonstrates these principles. I hope this Visual Basic 6 tutorial was helpful to you. Feel free to ask in questions or leave in comments below.

This tutorail is released under the GNU Free Documentation License 1.2. The original can be found here.

If you enjoyed this post, subscribe for updates (it's free)

fgfdg

s Your junk at making vb stuff

well...

Your just an idiot for not being able to follow this tutorial properly.
Nice tut btw very well done and explains quite a bit about how to do this thanks:)

arrowkeys Control

Hi Can u tell me the code for arrow keys control?
why by u can use the arrow keys to control the movement of an object? thanks
please email to bih_hao@hotmail.com

bring up the Form_Keydown or

bring up the Form_Keydown or Picturebox_keydown sub then say
Form_Keydown(keycode as single,shift as single)
select case keycode
case vbKeyUP ' or vbkeydown, vbkeyleft, vbkeyright
'code here
end select
end sub

line-line intersection

Please post a line-line intersection program code . Thank you .

I found this function at

I found this function at www.vb-helper.com it should solve your situation:
' Return True if the segments intersect.
Private Function SegmentsIntersect(ByVal X1 As Single, _
    ByVal Y1 As Single, ByVal X2 As Single, ByVal Y2 As _
    Single, ByVal A1 As Single, ByVal B1 As Single, ByVal _
    A2 As Single, ByVal B2 As Single) As Boolean
Dim dx As Single
Dim dy As Single
Dim da As Single
Dim db As Single
Dim t As Single
Dim s As Single

    dx = X2 - X1
    dy = Y2 - Y1
    da = A2 - A1
    db = B2 - B1
    If (da * dy - db * dx) = 0 Then
        ' The segments are parallel.
        SegmentsIntersect = False
        Exit Function
    End If
    
    s = (dx * (B1 - Y1) + dy * (X1 - A1)) / (da * dy - db * _
        dx)
    t = (da * (Y1 - B1) + db * (A1 - X1)) / (db * dx - da * _
        dy)
    SegmentsIntersect = (s >= 0# And s <= 1# And _
                         t >= 0# And t <= 1#)

    ' If it exists, the point of intersection is:
    ' (x1 + t * dx, y1 + t * dy)
End Function