In this article we add collision detection to the game.
In order for any interaction to occur between the various elements in the game we need a way to determine if two objects are touching. This will allows us to have a bullet collide with an enemy ship, or an enemy ship to collide with the player.
Collision detection can be quite a complicated topic. There are many different ways to implement collision detection, but our needs are quite simple, so our collision detection will be quite straight forward.
First we need a way to define the area that an object occupies. Logically this will be the same area that the image representing the objects takes up, so we can obtain this information from the VisualGameObject class. In fact because every object that will participate in a collision is visually represented on the screen, and therefore extends the VisualGameObject class, the VisualGameObject class will be modified to hold all the properties and functions necessary to participate in collision detection.
VisualGameObject.cpp / VisualGameObject.h
We add a new property called collisionName, and two new functions: CollisionArea and Collision. [code]
The collisionName specifies the type of object this is to the collision system. Enemies would have a collision name of “Enemy”, the player would have a collision name of “Player”, the players weapons would have a name of “PlayerWeapon” etc. This property will be used to determine which objects will be able to collide with each other (we don't want the player to be able to collide with its own bullets).
The CollisionArea function returns a SDL_Rect (which is an SDL structure that represents a rectangle) which defines the area that the VisualGameObject is currently taking up. [code]
The Collision function is empty. It will be called when a collision has been detected, but it is up to any class the extends the VisualGameObject class to add some logic to this function.
EngineManager.cpp / EngineManager.h
The EngineManager gains a new property called collisionMap, which maps the collisionName of a VisualGameObject class against all the other collisionNames of VisualGameObjects that will collide with it. [code]
The collisionMap is populated by the AddCollidingPair function. Calling this functions defines who can collide with what. [code]
The collisions themselves are done in the new CheckCollisions functions. Each VisualGameObject in the baseObjects collection (as determined by dynamic_cast and the run time type information functionality of C++) is checked against every other VisualGameObject. If the two have been set to collide with each other their CollisionAreas are checked to see if they overlap, and if so their Collision function is called. [code]
BaseEnemy.cpp / BaseEnemy.h
Player.cpp / Player.h
Each object wishing to participate in the collision detection needs to set its collsionName property. For convenience a number of standard collsionNames have been defined in the CollisionIdentifiers.h file. [BaseEnemy code] [Player code]
In addition we need to implement some response to a collision. At this stage we only have the player and some enemies, so the only real response we can have is to remove the enemies once they have been involved in a collision. So in the Collision function the enemy simply calls its own Shutdown function, which will remove it from memory and from the game. [code]
ApplicationManager.cpp / ApplicationManager.h
Finally the map of those VisualGameObjects that will collide needs to be initialized. This is done by the ApplicationManager. [code]
With collision detection implemented we pave the way for all other interactions between game elements like weapons and powerups.
Download the source code here.
Read more in the SDL Programming Tutorial series