This is a guide you can use to determine if two
objects are intersecting, or have "collided." This
isn't the most efficient way of doing this. If the shapes you
are using are rectangular, there is a different (and more exact) way
of determining if they are intersecting which you can find in my
VB Rectangular Collision Detection
guide
(working on it).
This guide works best for circular objects,
and MAY work better then the Rectangular Collision guide for
irregularly shaped objects. If your program has objects that are
circular though, this is the guide for that project.
All that you need to do to tell if there is a
circular collision is to have the Central X and Central Y coordinates
of an object, and the width and height of the object, Here is how
you'd find the Central X and Central Y of an object with Left, Top,
Width, and Height properties:
Dim
CircleX1
As
Single,
CircleY1 As
Single
Dim
CircleX2
As
Single,
CircleY2 As
Single
CircleX1 = Object1.Left + Object1.Width / 2
CircleY1 = Object1.Top + Object1.Height / 2
CircleX2 = Object2.Left + Object2.Width / 2
CircleY2 = Object2.Top + Object2.Height / 2 |
The Central X and Central Y values that you
get are the centers of imaginary circles that will surround your
objects, where Object1 and Object2 are the two objects.
The radius of the circle can be determined in whichever manner works
best for your project.
1. You could use half either the width or
height of the object for the radius, whichever is SMALLER, this way
you can be certain that none of the object will be outside the
circle, which will later translate into there being no collision at
all unless that part of the object that the circle is over hits the
other object, which would like like this :
2. You could use half either the width or height of the object for
the radius, whichever is BIGGER, this way you can be certain that
none of the object will be outside the circle, which will later
translate into there being a collision if almost any of the object
intersects the other object :
3. OR you could use the average of #1 and
#2, which would sometimes work better, it would look like this: 
This is how you would find the radius of the
object using the three methods above.
Dim
CircleRadius1
As
Single,
CircleRadius2 As
Single
'Method #1
If Object1.Width
> Object1.Height Then
CircleRadius1
= Object1.Height / 2
Else
CircleRadius1
= Object1.Width / 2
End If
If
Object2.Width > Object2.Height Then
CircleRadius2
= Object1.Height / 2
Else
CircleRadius2
= Object1.Width / 2
End If
'Method #2
If Object1.Width
< Object1.Height Then
CircleRadius1
= Object1.Height / 2
Else
CircleRadius1
= Object1.Width / 2
End If
If Object2.Width
< Object2.Height Then
CircleRadius2
= Object1.Height / 2
Else
CircleRadius2
= Object1.Width / 2
End If
'Method #3
CircleRadius1
= (Object1.Height / 2 + Object1.Width
/ 2) / 2
CircleRadius2
= (Object2.Height / 2 + Object2.Width
/ 2) / 2 |
Obviously the last option takes less code, so
that's what I usually use, but you should try them out and see which
one works best for whatever you're doing. In general, as long as
a game is going relatively fast, even if this isn't perfect it will
work for you.
So now, You have two circles, with a central point, and a radius:
For now we'll ignore the circles for a second
and just look at the centers of them. The key to this is to find
how far apart the center of the two objects are. Which requires
a little bit of math. The triangle that's formed you can see
below.
The two acute angles of the triangle have vertexes
at the centers of the two objects, the point at the right angle creates
a right triangle. The length of the two sides are the differences
between the two X values, and the two Y values. Now if you use the
Pythagorean theorem [A2 + B2 = C2], you
can find the hypotenuse, which is the length between the centers.
To do this in code:
Dim DifY
As
Single,
DifX As
Single
Dim Distance As
Single
DifY = CircleY1 - CircleY2
DifX = CirlcleX1 - CircleX2
Distance = Sqr(DifY
^ 2 + DifX ^ 2) |
- Where CircleY1, CircleY2, CirlcleX1,
and CircleX2 came from the above code. Now you have the
Distance between the two centers, how is that useful you may
ask. I'm not exactly sure how to describe this in words, so
first I'll show you two pictures, the left of two objects (circles,
like we would have found above) that aren't intersecting, the right
of two objects (circles) that are intersecting.
So how do we tell if we have the left or the
right going on, in code? Well we have to compare the sum of the
two circles radii with the distance between there centers. If
the sum of the radii is less then the distance between the centers of
the two circles, then there is no intersection, as you can see in the
left picture. If the sum of the radii is greater then the
distance between the centers of the two circles, then the circles ARE
intersecting, as you can see in the right picture. Here is how
you would tell using code:
Dim RadSum
As
Single
RadSum = CircleRadius1 + CircleRadius2
If Distance <
RadSum Then
'Your Collision Code
End If |
Where CircleRadius1, CircleRadius2,
and Distance are from above. Now we can put it all
together to get the final check (We'll use Method 3 for finding the
radius):
Public Sub CollisionCheck(Object1
As
Object,
Object1 As
Object)
Dim
CircleX1
As
Single,
CircleY1 As
Single
Dim
CircleX2
As
Single,
CircleY2 As
Single
Dim
CircleRadius1
As
Single,
CircleRadius2 As
Single
Dim DifY
As
Single,
DifX As
Single
Dim Distance As
Single
Dim RadSum
As
Single
CircleX1 = Object1.Left + Object1.Width / 2
CircleY1 = Object1.Top + Object1.Height / 2
CircleX2 = Object2.Left + Object2.Width / 2
CircleY2 = Object2.Top + Object2.Height / 2
'Method #3 for finding Circle
Radius
CircleRadius1
= (Object1.Height / 2 + Object1.Width
/ 2) / 2
CircleRadius2
= (Object2.Height / 2 + Object2.Width
/ 2) / 2
DifY = CircleY1 - CircleY2
DifX = CirlcleX1 - CircleX2
Distance = Sqr(DifY
^ 2 + DifX ^ 2)
RadSum = CircleRadius1 + CircleRadius2
If Distance <
RadSum Then
'Your Collision Code
End If
End Sub |
I used this code in my Skelly
and my Nosam games, you can check that out to
see it in action. Any other questions Email
me.
|