Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Beginning C++ Game Programming. - Second Edition

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

Product type Book
Published in Oct 2019
Publisher Packt
ISBN-13 9781838648572
Pages 746 pages
Edition 2nd Edition
Languages
Author (1):
John Horton John Horton
Profile icon John Horton

Table of Contents (25) Chapters

Preface 1. Chapter 1: C++, SFML, Visual Studio, and Starting the First Game 2. Chapter 2: Variables, Operators, and Decisions – Animating Sprites 3. Chapter 3: C++ Strings and SFML Time – Player Input and HUD 4. Chapter 4: Loops, Arrays, Switches, Enumerations, and Functions – Implementing Game Mechanics 5. Chapter 5: Collisions, Sound, and End Conditions – Making the Game Playable 6. Chapter 6: Object-Oriented Programming – Starting the Pong Game 7. Chapter 7: Dynamic Collision Detection and Physics – Finishing the Pong Game 8. Chapter 8: SFML Views – Starting the Zombie Shooter Game 9. Chapter 9: C++ References, Sprite Sheets, and Vertex Arrays 10. Chapter 10: Pointers, the Standard Template Library, and Texture Management 11. Chapter 11: Collision Detection, Pickups, and Bullets 12. Chapter 12: Layering Views and Implementing the HUD 13. Chapter 13: Sound Effects, File I/O, and Finishing the Game 14. Chapter 14: Abstraction and Code Management – Making Better Use of OOP 15. Chapter 15: Advanced OOP – Inheritance and Polymorphism 16. Chapter 16: Building Playable Levels and Collision Detection 17. Chapter 17: Sound Spatialization and the HUD 18. Chapter 18: Particle Systems and Shaders 19. Chapter 19: Game Programming Design Patterns – Starting the Space Invaders ++ Game 20. Chapter 20: Game Objects and Components 21. Chapter 21: File I/O and the Game Object Factory 22. Chapter 22: Using Game Objects and Building a Game 23. Chapter 23: Before You Go... 24. Other Books You May Enjoy

Chapter 19: Game Programming Design Patterns – Starting the Space Invaders ++ Game

Welcome to the final project. As you have come to expect by now, this project will take a significant step forward in terms of learning new C++ techniques. The next four chapters will look at topics such as smart pointers, C++ assertions, using a gamepad controller, debugging using Visual Studio, casting pointers of a base class to become pointers of a specific derived class, debugging, and a first look at design patterns.

It is my guess that if you are going to make deep, large-scale games in C++, then design patterns are going to be a big part of your learning agenda in the months and years ahead. In order to introduce this vital topic, I have chosen a relatively simple but fun game to serve as an example. In this chapter, we'll find out a bit more about the Space Invaders ++ game, and then we can get on to the topic of design patterns and why we need them.

In this hefty chapter,...

Space Invaders ++

Have a look at the following three screenshots, which visually explain most of what we need to know about Space Invaders ++. Just in case you don't know already, Space Invaders is one of the earliest arcade games and was released in 1978. If you like a bit of history, you can read the Wikipedia Space Invaders game page here: https://en.wikipedia.org/wiki/Space_Invaders.

This first screenshot shows the simple starting screen of our game. For the purposes of discussing screens, which we'll do next, we will call this the select screen. The player has two choices to select from: quit or play. However, by the end of this chapter, you will know how to add and switch between as many screens as you like:

As you can see, in the preceding screenshot, there is a new feature we have not implemented before: clickable buttons. We will talk more about buttons and their counterparts, such as UI panels and screens, shortly.

The following...

Design patterns

A design pattern is a reusable solution to a coding problem. In fact, most games (including this one) will use multiple design patterns. The key point about design patterns is this: they are already proven to provide a good solution to a common problem. We are not going to invent any design patterns – we are just going to use some that already exist to solve the problem of our ever-expanding code.

Many design patterns are quite complicated and require further study beyond the level of this book if you want to even begin learning them. What follows is a simplification of a few key game development-related patterns that will help fulfill the second objective of this book. You're urged to continue your study to implement them more comprehensively and alongside even more patterns than will be discussed here.

Let's look at the design patterns that are used in the Space Invaders ++ project.

Screen, InputHandler, UIPanel, and Button

This project...

C++ smart pointers

Smart pointers are classes that we can use to get the same functionality as a regular pointer but with an extra feature – the feature being that they take care of their own deletion. In the limited way we have used pointers so far, it has not been a problem for us to delete our own memory, but as your code becomes more complex, and when you are allocating the new memory in one class but using it in another class, it becomes much less clear which class is responsible for deleting the memory when we are done with it. And how can a class or function know whether a different class or function has finished with some allocated memory?

The solution is smart pointers. There are a few types of smart pointer; we will look at the two of the most commonly used ones here. The key to success with smart pointers is using the correct type.

The first type we will consider is shared pointers.

Shared pointers

The way that a shared pointer can safely delete the memory...

Casting smart pointers

We will often want to pack the smart pointers of derived classes into data structures or function parameters of the base class such as all the different derived Component classes. This is the essence of polymorphism. Smart pointers can achieve this using casting. But what happens when we later need to access the functionality or data of the derived class?

A good example of where this will regularly be necessary is when we deal with components inside our game objects. There will be an abstract Component class and derived from that there will be GraphicsComponent, UpdateComponent, and more besides.

As an example, we will want to call the update function on all the UpdateComponent instances each frame of the game loop. But if all the components are stored as base class Component instances, then it might seem that we can't do this. Casting from the base class to a derived class solves this problem.

The following code casts myComponent, which is a base...

C++ assertions

In this project, we will be using C++ assertions. As usual, there is more to this topic than we will discuss here, but we can still do some useful things with just an introduction.

We can use the #define preprocessor statement in a class to define a value for the entire project. We do so with the following code:

#define debuggingOnConsole

This code would be written at the top of a header file. Now, throughout the project, we can write code like the following:

#ifdef debuggingOnConsole
    // C++ code goes here
#endif

The #ifdef debuggingOnConsole statement checks whether the #define debuggingOnConsole statement is present. If it is, then any C++ code up to the #endif statement will be included in the game. We can then choose to comment out the #define statement to switch our debugging code on or off.

Typically, we will include code such as the following in the #ifdef blocks:

#ifdef debuggingOnConsole     ...

Creating the Space Invaders ++ project

You can find the runnable code that represents the project at the end of this chapter in the Space Invaders ++ folder. It will take all of chapters 20, 21, and 22 to complete and make the project runnable again. The completed code that is runnable and represents the project at the end of Chapter 22, Using Game Objects and Building a Game, can be found in the Space Invaders ++ 2 folder.

Create a new project in Visual Studio with the same settings that we used in the previous four projects. Call the new project Space Invaders ++.

Inside the Space Invaders ++ folder, copy and paste the fonts, graphics, and sound folders and their contents from the download bundle. The fonts, graphics, and sound folders, as you would expect, contain the font and graphical and audio assets we will use in this game.

In addition, you will need to download the background file from https://opengameart.org/content/background-night.

Important note

This image...

Where are we now?

At this stage, the only remaining errors in the code are the errors that refer to the SelectScreen class and the GameScreen class. It is going to take quite a bit of work to get rid of these errors and have a runnable program. The reason for this is that SelectScreen and GameScreen are derived from Screen and, in turn, the Screen class is also dependent on InputHandler, UIPanel, and Button. We will get to them next.

Coding the Screen class and its dependents

What we will do now is code all the screen-related classes. In addition, each of the screens from our game will have their own specific implementation of all these classes.

Next, we will code all the base classes; Screen, InputHandler, UIPanel, and Button. Following that, we will do the full implementation of the SelectScreen derivations of these classes and a partial implementation of the GameScreen derivations. At this point, we will be able to run the game and see our screens, UI panels, and buttons in action, and also be able to switch between screens. In the next chapter, we will work on the game properly and implement GameObject and LevelManager. In Chapter 22, Using Game Objects and Building a Game, we will see how we can use them all in the GameScreen class.

Coding the Button class

Create a new header file in the Header Files/Screens filter called Button.h and add the following code:

#pragma once
#include <SFML/Graphics...

Adding the WorldState.h file

Create a new header file in the Header Files/Engine filter called WorldState.h and add the following code:

#pragma once
class WorldState
{
public:
    static const int WORLD_WIDTH = 100;
    static int WORLD_HEIGHT;
    static int SCORE;
    static int LIVES;
    static int NUM_INVADERS_AT_START;
    static int NUM_INVADERS;
    static int WAVE_NUMBER;
};

These variables are public and static. As a result, they will be accessible throughout the project and are guaranteed to have only a single instance.

Coding the derived classes for the select screen

So far, we have coded the fundamental classes that represent the user interface, as well as the logical division of our game into screens. Next, we will code specific implementations of each of them. Remember that Space Invaders ++ will have two screens: select and game. The select screen will be represented by the SelectScreen class and will have a single UIPanel instance, a single InputHandler instance, and two buttons. The play screen will be represented by the GameScreen class and it will have two UIPanel instances. One is called GameUIPanel and will display the score, lives, and invader wave number. The other is called GameOverUIPanel and will display two buttons, giving the player the option to go back to the select screen or play again. As the GameScreen class is composed of two UIPanel instances, it will also be composed of two InputHandler instances.

Coding the SelectScreen class

Create a new header file in the Header...

Coding the derived classes for the game screen

The structure of all these classes is the same as the select screen-related classes. I will be sure to point out where they vary, however. Most of the significant differences will be discussed across the next three chapters, however, because that is when we will code all the game objects and components and then put them to work in the GameScreen class.

The first difference is that the GameScreen class has two UIPanel instances and two InputHandler instances.

Coding the GameScreen class

Create a new header file in the Header Files/Screens/Game filter called GameScreen.h and add the following code:

#pragma once
#include "Screen.h"
#include "GameInputHandler.h"
#include "GameOverInputHandler.h"
class GameScreen : public Screen
{
private:
    ScreenManagerRemoteControl* m_ScreenManagerRemoteControl;
    shared_ptr<GameInputHandler> m_GIH;
  ...

Running the game

If you run the game, you will see the select screen, as shown in the following screenshot:

Press Play to transition to the game screen:

Press Escape to quit, and go back to the select screen.

Quit the game and find the following line of code in the GameScreen class:

if (WorldState::LIVES <= 0)

Change it to the following:

if (true)

Now, run the game again and select the Play button. The game over panel will be displayed and can be interacted with:

Now, change back if (true) in the GameScreen class back to if (WorldState::LIVES <= 0).

Let's take a break; that was a long chapter.

Summary

You have achieved a lot in this chapter. You have built a solid foundation for the Space Invaders ++ game and you have also coded a reusable system that can be used for almost any game that is divided up into different "screens".

We now have an input handling system in place that can detect keyboard presses and mouse clicks and route the responsibility to handle them to a specific panel that is part of a specific screen. Furthermore, the abstraction of the concept of a screen allows us to set up as many different game loops as we like. The GameScreen class will be the main class to handle the logic of this game but, once you see how over the next few chapters, you could easily code another screen to play a completely different game. Of course, the most likely thing you will do is get started with your own ideas.

In the next chapter, we will code the game objects and components which are the basis of our entity-component pattern implementation.

...
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 2019 Publisher: Packt ISBN-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.
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}