Boulder Dash Part 2: Collision Detection
Sample project for implementing collision detection in the sprites of the Boulder Dash (Boulderdash) arcade game.
In our previous post we introduced the Firefly and Butterfly sprites and their movement rules around a random map. Now we're going to update the project to include collision detection and a new player sprite.
To start with though, we're going to do a little refactoring.
The ButterflySprite
and FireflySprite
classes share pretty
much the same movement code and will share exactly the same
collision code, so we'll merge the common behaviour into a new
abstract EnemySprite
class which these will inherit from.
We'll also add a protected constructor which will allow us to
specify the differences between the inherited sprites and their
movement rules.
With that done, we'll change FireflySprite
and
ButterflySprite
to inherit from EnemySprite
instead of
Sprite
, and update the constructors of these classes to call
the protected constructor to supply the movement rule
differences.
Finally, we'll remove the Move
methods from the two sprite
classes and instead let EnemySprite
implement the movement
code.
Although I won't go into this here, other refactoring we did was
to move the Sprites
collection from MainForm
into Map
. I
also added an IsScenery
method to the Map
class which
returns if a tile is considered scenery, for example a piece of
solid earth, or a boulder which can't currently move.
A basic load map system was also added. You can still use the "Create Random Map" to generate a mostly empty canvas for the sprites to move around in (clicking with the left button will add a new firefly, with the right a butterfly) or you can load the predefined map.
Now it's time to implement the actual collision detection. We'll do this by adding a new function to the base Sprite class that will check to see if a the location of any sprite matches a given location.
Note: This implementation assumes that only one sprite can occupy a tile at any one time, which is the case in Boulder Dash.
We're also using LINQ in this function for convenience. If you haven't yet upgraded to Visual Studio 2008/2010 you'll need to replace the call with a manual loop
I choose to implement the function as a bool
to allow it to be
easily used in an if
statement, but providing an out
parameter to return the matching sprite (or null otherwise).
With that done, it's time to update our movement code to also
perform the collision detection. The two conditions in the
Move
method which check if a tile is part of the scenery
will be modified to call out new method.
With this change, sprites on the map are now aware of each other and when they bump into each other they will automatically turn away.
Our example project now has collision detection in place for the enemy sprites. Being enemies of the player nothing happens when they bump into each other. If they bump into the player on the other hand...
Time to add a new sprite. The PlayerSprite
will be a non
functioning sprite masquerading as a player character.
In our previous modification the Move
method of our
EnemySprite
implementations we grab the sprite that we are
colliding with, but we don't do anything with it. Time to change
that.
We'll add a basic enum that will control what happens when a sprite hits another. For this demo, that will either be nothing, or "explode" killing both sprites.
We're also going to modify the base Sprite class with a new method:
Sprite implementations will override this method and return a
CollisionAction
based on the sprite they collided with.
The implementation for our new Player
class is quite
straightforward:
And the one for EnemySprite
is almost as easy:
Now we have this, we'll update the Move
method of our
EnemySprite
to take care of the action:
Note that if the Player
could move as well then it too would
need collision detection. However, as we only have one class
capable of movement we'll add the code just to that for now.
Also note that we had to adjust the original NextMove
method
in MainForm
otherwise it would crash when looping through the
sprite list and a removal occurred.
You can download an updated version of the sample project from the link below.
Like what you're reading? Perhaps you like to buy us a coffee?