Reader small image

You're reading from  Beginning C++ Game Programming. - Second Edition

Product typeBook
Published inOct 2019
Reading LevelIntermediate
PublisherPackt
ISBN-139781838648572
Edition2nd Edition
Languages
Right arrow
Author (1)
John Horton
John Horton
author image
John Horton

John Horton is a programming and gaming enthusiast based in the UK. He has a passion for writing apps, games, books, and blog articles. He is the founder of Game Code School.
Read more about John Horton

Right arrow

Chapter 11: Collision Detection, Pickups, and Bullets

So far, we have implemented the main visual aspects of our game. We have a controllable character running around in an arena full of zombies that chase them. The problem is that they don't interact with each other. A zombie can wander right through the player without leaving a scratch. We need to detect collisions between the zombies and the player.

If the zombies are going to be able to injure and eventually kill the player, it is only fair that we give the player some bullets for their gun. We will then need to make sure that the bullets can hit and kill the zombies.

At the same time, if we are writing collision detection code for bullets, zombies, and the player, it would be a good time to add a class for health and ammo pickups as well.

Here is what we will do and the order in which we will cover things in this chapter:

  • Shooting Bullets
  • Adding a crosshair and hiding the mouse pointer
  • Spawning pickups...

Coding the Bullet class

We will use the SFML RectangleShape class to visually represent a bullet. We will code a Bullet class that has a RectangleShape member, as well as other member data and functions. Then, we will add bullets to our game in a few steps, as follows:

  1. First, we will code the Bullet.h file. This will reveal all the details of the member data and the prototypes for the functions.
  2. Next, we will code the Bullet.cpp file, which, of course, will contain the definitions for all the functions of the Bullet class. As we step through this, I will explain exactly how an object of the Bullet type will work and be controlled.
  3. Finally, we will declare a whole array full of bullets in the main function. We will also implement a control scheme for shooting, managing the player's remaining ammo, and reloading.

Let's get started with step 1.

Coding the Bullet header file

To make the new header file, right-click Header Files in the Solution Explorer...

Making the bullets fly

We will make the bullets usable by following these six steps:

  1. Add the necessary include directive for the Bullet class.
  2. Add some control variables and an array to hold some Bullet instances.
  3. Handle the player pressing R to reload.
  4. Handle the player pressing the left mouse button to fire a bullet.
  5. Update all bullets that are in flight in each frame.
  6. Draw the bullets that are in flight in each frame.

Including the Bullet class

Add the include directive to make the Bullet class available:

#include <SFML/Graphics.hpp>
#include "ZombieArena.h"
#include "Player.h"
#include "TextureHolder.h"
#include "Bullet.h"
using namespace sf;

Let's move on to the next step.

Control variables and the bullet array

Here are some variables to keep track of clip sizes, spare bullets, bullets, the remaining bullets in the clip, the current rate of fire (starting at one per second), and...

Giving the player a crosshair

Adding a crosshair is easy and only requires one new concept. Add the following highlighted code, and then we can run through it:

// 100 bullets should do
Bullet bullets[100];
int currentBullet = 0;
int bulletsSpare = 24;
int bulletsInClip = 6;
int clipSize = 6;
float fireRate = 1;
// When was the fire button last pressed?
Time lastPressed;
// Hide the mouse pointer and replace it with crosshair
window.setMouseCursorVisible(true);
Sprite spriteCrosshair;
Texture textureCrosshair = TextureHolder::GetTexture("graphics/crosshair.png");
spriteCrosshair.setTexture(textureCrosshair);
spriteCrosshair.setOrigin(25, 25);
// The main game loop
while (window.isOpen())

First, we call the setMouseCursorVisible function on our window object. We then load a Texture and declare a Sprite instance and initialize it in the usual way. Furthermore, we set the sprite's origin to its center to make it convenient and simpler to make the bullets fly to the...

Coding a class for pickups

In this section, we will code a Pickup class that has a Sprite member, as well as other member data and functions. We will add pickups to our game in just a few steps:

  1. First, we will code the Pickup.h file. This will reveal all the details of the member data and the prototypes for the functions.
  2. Then, we will code the Pickup.cpp file which, of course, will contain the definitions for all the functions of the Pickup class. As we step through this, I will explain exactly how an object of the Pickup type will work and be controlled.
  3. Finally, we will use the Pickup class in the main function to spawn them, update them, and draw them.

Let's get started with step 1.

Coding the Pickup header file

To make the new header file, right-click Header Files in the Solution Explorer and select Add | New Item.... In the Add New Item window, highlight (by left-clicking) Header File (.h), and then, in the Name field, type Pickup.h.

Add and...

Using the Pickup class

After all that hard work implementing the Pickup class, we can now go ahead and write code in the game engine to put some pickups into the game.

The first thing we will do is add an include directive to the ZombieArena.cpp file:

#include <SFML/Graphics.hpp>
#include "ZombieArena.h"
#include "Player.h"
#include "TextureHolder.h"
#include "Bullet.h"
#include "Pickup.h"
using namespace sf;

In this following code, we are adding two Pickup instances: one called healthPickup and another called ammoPickup. We pass the values 1 and 2, respectively, into the constructor so that they are initialized to the correct type of pickup. Add the following highlighted code, which we have just discussed:

// Hide the mouse pointer and replace it with crosshair
window.setMouseCursorVisible(true);
Sprite spriteCrosshair;
Texture textureCrosshair = TextureHolder::GetTexture(
       ...

Detecting collisions

We just need to know when certain objects from our game touch certain other objects. We can then respond to that event in an appropriate manner. In our classes, we have already added functions that will be called when our objects collide. They are as follows:

  • The Player class has a hit function. We will call it when a zombie collides with the player.
  • The Zombie class has a hit function. We will call it when a bullet collides with a zombie.
  • The Pickup class has a gotIt function. We will call it when the player collides with a pickup.

If necessary, look back to refresh your memory regarding how each of those functions works. All we need to do now is detect the collisions and call the appropriate functions.

We will use rectangle intersection to detect collisions. This type of collision detection is straightforward (especially with SFML). We will use the same technique that we used in the Pong game. The following image shows how a rectangle...

Summary

This was a busy chapter, but we achieved a lot. Not only did we add bullets and pickups to the game through two new classes, but we also made all the objects interact as they should by detecting when they collide with each other.

Despite these achievements, we need to do more work to set up each new game and to give the player feedback through a HUD. In the next chapter, we will build the HUD.

FAQ

Here are some questions that might be on your mind:

Q) Are there any better ways of doing collision detection?

A) Yes. There are lots more ways to do collision detection, including but not limited to the following.

  • You can divide objects up into multiple rectangles that fit the shape of the sprite better. It is perfectly manageable for C++ to check on thousands of rectangles each frame. This is especially the case when you use techniques such as neighbor checking to reduce the number of tests that are necessary each frame.
  • For circular objects, you can use the radius overlap method.
  • For irregular polygons, you can use the passing number algorithm.

You can review all of these techniques, if you wish, by taking a look at the following links:

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Beginning C++ Game Programming. - Second Edition
Published in: Oct 2019Publisher: PacktISBN-13: 9781838648572
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
John Horton

John Horton is a programming and gaming enthusiast based in the UK. He has a passion for writing apps, games, books, and blog articles. He is the founder of Game Code School.
Read more about John Horton