Basic Collision Detection
Source code: http://silverlightrocks.com/cs/files/folders/slg101_tutorials/entry250.aspx
It's all well and good to move objects around, and create particles, but most games require some kind of collision handling. A collision is when two objects intersect. There are many different ways to determine if two objects collide, each with varying levels of complexity and accuracy. In 2D games, the most accurate and complex is probably "pixel perfect" collision which checks whether any pixel of the two objects overlap. You can also use bounding boxes, or polygons that approximate the outline, and calculate if the two polygons intersect. One of the simplest collision detection algorithms is to use bounding circles, or in 3D bounding spheres. The math for this type of collision is very straightforward, and can also be used as an intermediate collision detection step before more complex and CPU intensive algorithms.
Collisions can get very involved if you're dealing with multiple objects potentially colliding simultaneously, or dealing with gravity and other forces along with the collisions. It also adds a major level of complexity if the objects that collide need to bounce off of each other. One of the core features of most commercial game engines is a physics engine, which specifically handles these types of interactions.
Fortunately in our case, we don't need to handle objects bouncing off each other. When objects collide in our game, they explode. We also can approximate our objects with circles, and therefore use the simplest of collision detection routines.
The first collision we will want to handle is between the ship and the asteroids. Since there is such as small number of potential objects, we can simply loop through the list of asteroids and check if they collide with the ship. To check if two circles intersect, you can find the distance between the centers and if that value is smaller than the sum of the radii of the two circles, then the circles intersect. The distance between two points can be found using the pythagorean theorem, and the distance is the square root of the sum of the X distance squared and the Y distance squared. To make things easier, the Vector type has a Length method which can help with the calculation. So since the ship and asteroids inherit from the sprite class, it makes sense to put the logic in the Sprite class to calculate whether a collision occurs. Here is the Collides method for the Sprite class:
public static bool Collides(Sprite s1, Sprite s2)
Vector v = new Vector(s1.Position.X - s2.Position.X, s1.Position.Y - s2.Position.Y);
if (s1.CollisionRadius + s2.CollisionRadius > v.Length)
The CollisionRadius is a field that has been added to the Sprite class to store the collision radius, I know, very creative naming... Now for a useful game programming tip. To account for irregularities in the object (for example, the ship isn't really round, and the asteroids are bumpy) make your collision radius smaller than the radius that would encompass the entire sprite. This also makes the gameplay a little more forgiving and actually feels a little more natural.
So now in the gameLoop_Update method, we need to call this collision method. If the objects collide, the ship will explode and the asteroid will explode. If the asteroid has a radius of more than 10, we'll split it into two new asteroids and remove the existing one. To make it easier to remove items from a collection, it is helpful to loop backwards. This is because if you're looping forwards and remove an item, the indexes will be off. Also any new objects that are added will be processed immediately, which isn't what we want.
for (int i = asteroids.Count - 1; i >= 0; i--)
if (Sprite.Collides(ship, asteroids[i]))
if (asteroids[i].Radius > 10)
Asteroid a1 = new Asteroid(asteroids[i].Radius / 2);
a1.Position = asteroids[i].Position;
Asteroid a2 = new Asteroid(asteroids[i].Radius / 2);
a2.Position = asteroids[i].Position;
Then for the Explode method, this is also added to the Sprite class, since both a ship and an asteroid can explode. The Explode method generates a set of particles that fly out in all directions from the current position. It's pretty similar to the AddExhaust method and looks like this:
public void Explode()
ParticleFactory p = new ParticleFactory();
p.FromOpacity = 1;
p.ToOpacity = .3f;
p.LifeSpanSeconds = 1f;
p.StartPosition = this.Position;
for (int i = 0; i < 20; i++)
Ellipse ellipse = XamlReader.Load(explodeXaml) as Ellipse;
Vector velocity = MathHelper.CreateVectorFromAngle(rand.Next(360), rand.Next(60, 100));
Now I haven't gone through all of the code changes, some things were moved around, and other fields added, but I have covered the main code related to collision handling for the game. The rest of it is similar to things we have already covered, or is just basic programming and not related to game programming or Silverlight specifically. Please look through the latest code to get an idea for the other changes.
All Tutorials Updated for Silverlight 1.1 Alpha Refresh
I have gone back through all of my posts and updated the ZIP files that contain the full source, and made any changes to the source and the tutorials required by the Silverlight 1.1 Alpha Refresh. The only breaking change that really impacted the tutorials so far was that all Storyboard objects now need to be named. I look forward to continuing this series soon, with the next post focusing on simple Particles.
Please let me know if there is anything I missed while bringing everything up to date.