Learn C++ for Game Development
()
About this ebook
If you’re new to C++ but understand some basic programming, then Learn C++ for Game Development lays the foundation for the C++ language and API that you’ll need to build game apps and applications.
Learn C++ for Game Development will show you how to:
- Master C++ features such as variables, pointers, flow controls, functions, I/O, classes, exceptions, templates, and the Standard Template Library (STL)
- Use design patterns to simplify your coding and make more powerful games
- Manage memory efficiently to get the most out of your creativity
- Load and save games using file I/O, so that your users are never disappointed
Most of today's popular console and PC game platforms use C++ in their SDKs. Even the Android NDK and now the iOS SDK allow for C++; so C++ is growing in use for today's mobile game apps. Game apps using C++ become much more robust, better looking, more dynamic, and better performing. After reading this book, you’ll have the skills to become a successful and profitable game app or applications developer in today’s increasingly competitive indie game marketplace.
The next stage is to take the foundation from this book and explore SDKs such as Android/Ouya, PlayStation, Wii, Nintendo DS, DirectX, Unity3D, and GameMaker Studio to make your career really take off.
Read more from Bruce Sutherland
Beginning Android C++ Game Development Rating: 0 out of 5 stars0 ratingsC++20 Recipes: A Problem-Solution Approach Rating: 0 out of 5 stars0 ratings
Related to Learn C++ for Game Development
Related ebooks
C# Deconstructed: Discover how C# works on the .NET Framework Rating: 0 out of 5 stars0 ratingsPractical ASP.NET Web API Rating: 0 out of 5 stars0 ratingsVisual Studio Condensed: For Visual Studio 2013 Express, Professional, Premium and Ultimate Editions Rating: 0 out of 5 stars0 ratingsPro TypeScript: Application-Scale JavaScript Development Rating: 4 out of 5 stars4/5Design Patterns in Modern C++: Reusable Approaches for Object-Oriented Software Design Rating: 0 out of 5 stars0 ratingsC++17 Quick Syntax Reference: A Pocket Guide to the Language, APIs and Library Rating: 0 out of 5 stars0 ratingsMicrosoft Conversational AI Platform for Developers: End-to-End Chatbot Development from Planning to Deployment Rating: 0 out of 5 stars0 ratingsBasic Guide to Programming Languages Python, JavaScript, and Ruby Rating: 0 out of 5 stars0 ratings.NET IL Assembler Rating: 0 out of 5 stars0 ratingsMATLAB Optimization Techniques Rating: 0 out of 5 stars0 ratingsEmbedded Software Design and Programming of Multiprocessor System-on-Chip: Simulink and System C Case Studies Rating: 0 out of 5 stars0 ratingsPro Cryptography and Cryptanalysis: Creating Advanced Algorithms with C# and .NET Rating: 0 out of 5 stars0 ratings.NET DevOps for Azure: A Developer's Guide to DevOps Architecture the Right Way Rating: 0 out of 5 stars0 ratingsFPGA prototyping The Ultimate Step-By-Step Guide Rating: 0 out of 5 stars0 ratingsModern Arm Assembly Language Programming: Covers Armv8-A 32-bit, 64-bit, and SIMD Rating: 0 out of 5 stars0 ratingsAssessing and Improving Prediction and Classification: Theory and Algorithms in C++ Rating: 0 out of 5 stars0 ratingsBeginning Application Lifecycle Management Rating: 0 out of 5 stars0 ratingsBare-Metal Embedded C Programming: Develop high-performance embedded systems with C for Arm microcontrollers Rating: 0 out of 5 stars0 ratingsPro ASP.NET 4.5 in C# Rating: 0 out of 5 stars0 ratingsBeginning C: From Beginner to Pro Rating: 0 out of 5 stars0 ratingsMastering C++ Network Automation Rating: 0 out of 5 stars0 ratingsMastering the Raspberry Pi Rating: 3 out of 5 stars3/5How Open Source Ate Software: Understand the Open Source Movement and So Much More Rating: 0 out of 5 stars0 ratingsScience and Engineering Projects Using the Arduino and Raspberry Pi: Explore STEM Concepts with Microcomputers Rating: 0 out of 5 stars0 ratingsAdvanced Robotic Vehicles Programming: An Ardupilot and Pixhawk Approach Rating: 0 out of 5 stars0 ratingsPatterns in the Machine: A Software Engineering Guide to Embedded Development Rating: 5 out of 5 stars5/5Java EE 7 Recipes: A Problem-Solution Approach Rating: 0 out of 5 stars0 ratingsLearn Java for Android Development: Java 8 and Android 5 Edition Rating: 0 out of 5 stars0 ratingsModern Data Mining Algorithms in C++ and CUDA C: Recent Developments in Feature Extraction and Selection Algorithms for Data Science Rating: 0 out of 5 stars0 ratings
Software Development & Engineering For You
Learn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5Hand Lettering on the iPad with Procreate: Ideas and Lessons for Modern and Vintage Lettering Rating: 4 out of 5 stars4/5Managing Humans: Biting and Humorous Tales of a Software Engineering Manager Rating: 4 out of 5 stars4/5Python For Dummies Rating: 4 out of 5 stars4/5Grokking Algorithms: An illustrated guide for programmers and other curious people Rating: 4 out of 5 stars4/5How Do I Do That in Photoshop?: The Quickest Ways to Do the Things You Want to Do, Right Now! Rating: 4 out of 5 stars4/5Beginning Programming For Dummies Rating: 4 out of 5 stars4/5Tiny Python Projects: Learn coding and testing with puzzles and games Rating: 4 out of 5 stars4/5Data Visualization: a successful design process Rating: 4 out of 5 stars4/5PYTHON: Practical Python Programming For Beginners & Experts With Hands-on Project Rating: 5 out of 5 stars5/5Agile Practice Guide Rating: 4 out of 5 stars4/5SQL For Dummies Rating: 0 out of 5 stars0 ratingsGray Hat Hacking the Ethical Hacker's Rating: 5 out of 5 stars5/5How to Write Effective Emails at Work Rating: 4 out of 5 stars4/5Coding with AI For Dummies Rating: 0 out of 5 stars0 ratingsEngineering Management for the Rest of Us Rating: 5 out of 5 stars5/5Lua Game Development Cookbook Rating: 0 out of 5 stars0 ratingsFlow: A Handbook for Change-Makers, Mavericks, Innovators and Leaders Rating: 0 out of 5 stars0 ratingsRy's Git Tutorial Rating: 0 out of 5 stars0 ratingsEmbedded Linux Development with Yocto Project Rating: 0 out of 5 stars0 ratingsLearning Python Rating: 5 out of 5 stars5/5JIRA 7 Essentials - Fourth Edition Rating: 5 out of 5 stars5/5Beginning C++ Game Programming - Second Edition: Learn to program with C++ by building fun games, 2nd Edition Rating: 0 out of 5 stars0 ratingsHacking for Beginners: Mastery Guide to Learn and Practice the Basics of Computer and Cyber Security Rating: 0 out of 5 stars0 ratingsPhotoshop For Beginners: Learn Adobe Photoshop cs5 Basics With Tutorials Rating: 0 out of 5 stars0 ratingsThe Inmates Are Running the Asylum (Review and Analysis of Cooper's Book) Rating: 4 out of 5 stars4/5
Reviews for Learn C++ for Game Development
0 ratings0 reviews
Book preview
Learn C++ for Game Development - Bruce Sutherland
© Bruce Sutherland 2014
Bruce SutherlandLearn C++ for Game Development10.1007/978-1-4302-6458-3_1
1. Beginning C++
Bruce Sutherland¹
(1)
VIC, Australia
The C++ programming language was designed by Bjarne Stroustrup at Bell Labs, beginning in 1979. The goal of the language was to provide useful features from other languages of the time, such as Simula, with faster runtime performance. C was chosen as the basis for this new language due to its execution speed, portability, and wide adoption.
The first major extension Stroustrup added to C was class support. Classes allowed a new programming paradigm to be used with C: object-oriented programming (OOP). Stroustrup’s new language quickly became known as C with Classes, eventually changed to C++ in 1983.
C++ has been in continual development since its inception. New features were added regularly throughout the 1980s and 1990s and many of these have become essential tools for game developers. Examples of these features that are covered in this book are virtual functions, templates, and the Standard Template Library.
An ISO standard for C++ was first published in 1998. Standardizing a language gives compiler writers a common set of features to implement if they wish to achieve C++ compatibility. Standardization also benefits programmers writing code in C++ as it allows them to use a common set of features that they can expect to behave in the same way when using multiple compilers or multiple operating systems and computer architectures. There have been four C++ standards released to date. The original standard is known as C++98. C++98 was added to with C++03, and new experimental features were added to the language with C++TR1 (C++ Technical Review 1). The current C++ standard is C++11.
This book focuses on the most up-to-date version of the standard. However, this presents us with some challenges, as not all compilers have been updated to support all of the latest features of C++’. It can be taken for granted that when I refer to C++ in this book I mean C++11; any topics that require explicit reference to older C++ standards will be clear. The Microsoft’ C++ compiler included with its Visual Studio integrated development environment (IDE), for example, does not include support for constant expressions or type aliasing. (Don’t worry if you don’t understand these terms; they are new C++11 features and are covered in the section relating to templates.) Notes are added to the text in sections where relevant features are not supported by one of the major compilers.
Compilers
C++ is a compiled language; this means that the code is read by a program that converts the text source files created by a programmer into instructions that can be executed by a processor. Different settings in compilers, or different compilers, can be used to turn source files into instructions suitable for completely different processor architectures, such as x86 and Armv7.
The major compilers currently in use are the following:
Microsoft Visual C++ Compiler (MSVC)
GNU Compiler Collection (GCC)
Apple LLVM
Clang
These are the compilers that this book is most concerned with, as they are the most likely to be encountered by game developers. MSVC is the compiler included with the Microsoft Visual Studio IDE and used when writing programs for Windows and Microsoft game consoles such as the Xbox One. GCC is common on Linux platforms and is the default compiler used when building native Android applications. Apple LLVM is the C++ compiler used when building OS X and iOS applications. Clang is a relatively new program that acts as the front end for the LLVM compiler (also used in the Apple ecosystem) and is included as an optional compiler by the current Android Native Development Kit (NDK).
Some of the samples included in this book might not compile on your compiler of choice if that compiler is incompatible with all of the latest features of C++11. Switching compilers if possible or updating your software to the latest versions are possible options to work with these features.
Programming Paradigms
Programming paradigms are closely related to high-level programming styles. C++ does not enforce a particular paradigm and provides flexible features to enable programmers to program in the following paradigms.
Procedural Programming
Procedural programming involves writing ordered statements in blocks known as functions (also known as procedures). Functions are used to encapsulate code that can be reused and to improve code readability. C is also a procedural language and C++ contains the entire C language as a subset, allowing C++ programs to be written in a fully procedural manner. Part 1 of this book covers the aspects of C++ necessary to write procedural programs.
Object-Oriented Programming
OOP is supported through the addition of classes to C++. OOP involves designing a program as a set of discrete objects. These objects hide their implementation and data from the calling code (encapsulation), which allows specific implementation details to be changed at a later time without affecting other sections of the program. Inheritance and polymorphism are other important aspects of the C++ OOP paradigm. OOP programming is the focus of Part 2 in this book.
Generic Programming
Generic programming is most likely the least understood paradigm in C++ despite its widespread use via the Standard Template Library. Templates allow programmers to write classes that can operate on different types via specializations. Template metaprogramming is a powerful technique that confers the ability to write programs within the code that generate values and code at compile time. Templates and Metaprogramming are covered in Part 4 of this book.
C++ Game Programming
C++ has been a major language of choice for game developers since its inception. All major gaming platforms have supported and currently support C++ compilation. This includes Windows, Linux, OS X, iOS, Xbox One, PlayStation 4, Wii U, and Android.
Part 5 of this book covers advanced C++ topics that programmers will find useful as hardware becomes more powerful. These include design patterns, streams, memory management, concurrency (multithreaded programming), and a look at how we can write code that supports multiple game development platforms.
Our First C++ Program
Let’s take a look at a simple C++ program before we get started with the details of C++. Listing 1-1 shows a simple C++ program written in Microsoft Visual Studio Express 2012 for Windows Desktop.
Listing 1-1. Our First C++ Program
// Chapter1.cpp : Defines the entry point for the console application.
//
#include stdafx.h
#include
#include
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cout << What is your name?
<< endl;
string name {};
cin >> name;
cout << You said your name is:
<< name << endl;
return 0;
}
The first two lines of this source code are comments. A double forward slash indicates that all text following the // on the same line should be ignored by the compiler. Block comments are also supported and are opened with /* and closed with */. You will see several uses of both forms of comment throughout this book.
There are then several lines beginning with #include. This tells the compiler to include other files into our program. We cover the difference between source and header files in Chapter 6.
The next line tells the compiler that we want to use the standard namespace. Namespaces are also covered in Chapter 6.
The program then begins with the _tmain function. This is the first function called by the program when writing Windows applications that target the console. Different operating systems have different entry points and you’ll see these throughout this book as different examples are written to target different operating systems and compilers. You should be able to easily alter the samples to use the entry point for your system of choice.
The cout operator writes the text following the << operator to the console window. The cin operator stops the program and waits for the user to enter text. We store the text entered into the name variable and then use it to echo back the input the user entered.
The last line returns the value 0 from the function to let the operating system know that we finished without error.
As you can see, this simple program asks for the user’s name and then repeats that name back to the user. Congratulations: You’ve written your first C++ program.
Summary
This chapter has given you a very brief introduction to the C++ programming language. We’ve looked at the basic history of the language, the current main C++ compilers, its major paradigms, and a simple C++ program.
The next chapters look at how we can create some simple games using the C features of C++, beginning with a look at the fundamental built-in types and operators in C++.
The examples in Chapters 2 and 3 are simple programs that will help you to understand how C++ types and operators behave. The examples beginning in Chapter 4 see us begin to create a text adventure game that we will develop to completion throughout the remainder of the book. Text adventure games were very popular on early computers and they are an excellent way to learn C++ for game development without requiring you to learn the intricacies of a platform-specific windowing system or graphics application programming interface (API).
Part 1
Procedural Programming
Procedural Programming
The roots of the C++ programing language come from the C programming language. C provides the basis for the C++ procedural programming paradigm.
Procedural programming involves using variables and functions to create reusable procedures that constitute a full program. This part of the book introduces you to the features provided in C++ that would allow you to write fully procedural programs.
This part of the book begins by looking at C++’s built-in types, operators, arrays, pointers and references, and functions before finally looking at flow control statements and methods of structuring your programs.
© Bruce Sutherland 2014
Bruce SutherlandLearn C++ for Game Development10.1007/978-1-4302-6458-3_2
2. Writing a Guessing Game with C++ Types
Bruce Sutherland¹
(1)
VIC, Australia
You will begin the process of learning C++ by learning about the different built-in types that the language supports. C++ has built-in support for integers, floating point numbers, booleans, and enumerators. This chapter covers all of these types. We also look at the different types of operators that can be used to manipulate and compare these types of values. It is useful to understand how C++ handles variables before we begin to create programs in the language. To start, we take a look at the difference between dynamically and statically typed languages, which includes how we declare and define variables in C++.
Dynamic Versus Static Typed Languages
Variables in programming languages can be handled in two different ways. Dynamically typed languages do not require the programmer to state explicitly which type should be used to store the value. Dynamically typed languages can switch the type of a variable on the fly depending on how it is being used.
Statically typed languages require the programmer to tell the compiler explicitly which type to use to represent the data the variable will store. C++ is a statically typed language and creating variables in C++ is a two-step process.
Declaring Variables
When we are introducing a new variable into a program, we are said to be declaring the variable. This essentially means that we are telling the compiler that we would like to have a variable of a specific type and with a specific name. C++ compilers require that all variables be declared before they can be used in our programs. An example of a variable declaration would be:
int numberOfObjects;
This declaration tells the compiler that we would like to have an integer with the name numberOfObjects; it does not tell the compiler what the variable contains or what it should be used for.
Defining Variables
We can define our variable once we have declared it. Defining a variable involves telling the compiler what its initial value should be. This is an example of a variable definition:
numberOfObjects = 0;
It's fairly common that we will define and declare some variables at the same time. Combining the declaration and definition would resemble this line:
int numberOfObjects = 0;
We'll be looking at the places where it is appropriate to declare names to the compiler compared to defining them as we move through this book. The rules for declaring and defining different variables and types depend on the context in which they are being used.
Integers
The first set of types that we will be looking at in C++ is the integer types. The previous sections have already shown how to declare and define an integer variable. To recap:
int numberOfObjects = 0;
This line of code declares and defines an integer variable. What this means to the compiler is that we want to create a variable that is capable of storing whole numbers. Examples of integers are –1000, 0, 24, and 1345219. Integers can contain both positive and negative numbers.
The type int is just one of several different types that can store integers. The others are char, short, and long. Table 2-1 shows the different ranges of values that can be stored in these types when using MSVC.
Table 2-1.
The MSVC Integral Types, with Minimum and Maximum Values
As you can see there are five main types of integers when using C++. It's important to select a variable that can accommodate all of the possible values you might wish to store. Failing to use a type with enough possible values results in wrapping. That means that if you had a char variable that currently stored 127 and you tried to add a one, the value in the variable would wrap and your variable would then contain –128.
Unsigned Integers
C++ also supports unsigned versions of the integer types shown in Table 2-1. Table 2-2 shows the ranges that these unsigned variable types can store.
Table 2-2.
MSVC's Unsigned Integral Type Ranges
Using unsigned types extends the range of available positive integers at the expense of losing all negative integers. These types should be used in all cases where negative numbers will not be needed.
Two’s Complement
Before we move on to look at some other types of variables, it is important to understand how the integer values we have covered are represented by the computer. You’ve seen that unsigned numbers of varying numbers of bytes can store numbers ranging from 0 through to their maximum size. In the case of a single-byte char that maximum number is 255.
This happens because a single byte is made up of 8 individual bits. Each bit represents the next power of two from the last. Table 2-3 shows how you can think of the bits in a byte.
Table 2-3.
The Bits Making Up a Single Byte: The Top Row Shows the Bit Number and the Bottom Row Shows the Value This Byte Represents When Using Unsigned Variables
Table 2-3 shows the bit values for an unsigned char. When we have an unsigned char variable that stores the value 255, all of the bits are turned on. This would be represented by 11111111 in binary. If we add a 1 to this number the values will wrap and we will end up back at 00000000 as the 8 bits cannot store a higher value. This is something that you will need to be aware of when using unsigned integer variables.
When you want to represent negative numbers using signed variables, the processor will use Two’s Complement. Two’s Complement works by using the highest bit to represent whether the number is positive or negative. The highest positive number that can be stored in a char variable is 127 and is represented in binary by 01111111. Adding 1 to this number gives us 10000000, which is –128 and once again shows you how wrapping occurs in practice.
Switching between a positive and negative number is a simple process. You have to switch all of the bits and add one. The number 1 is represented in binary by 00000001. To flip 1 to -1 we first flip all of the bits to 11111110 (which is -2), then add 1 to give us 11111111.
This is a brief introduction to how a processor represents the integer values your programs will store in memory. We will cover some more binary representations of numbers in Chapter 3 when we look at binary operators.
Floating Point Numbers
Floating point numbers in C++ are used to represent numbers with a decimal point. Examples of these are –10.5, 0.3337, and 89.8376.
Like the signed integer types, floats can be used to store positive and negative numbers. Unlike integers, though, there are no unsigned versions of floating point numbers. Defining a floating point is done in the following way:
float decimalNumber = 1.0f;
When defining floating point variables in code, the value must be followed by an f. The reason for this is that a number with a decimal point but no f is a double.
The current floating point standards require that floats be represented with 32 bits (or 4 bytes). Thirty-two-bit floating point numbers might not have a large enough range for what we would like to achieve under given circumstances, so C++ also supplies the double type. The float type can be thought of as a single precision floating point number and the double type is then a double precision floating point number. A double can be defined as follows:
double doubleNumber = 1.0;
Single precision floats are usually sufficient for all but a few scenarios in game development and are generally faster and more efficient for the types of tasks we carry out.
Boolean Values
Booleans are simple values that can only contain true or false. Booleans are usually, but not always, implemented as a single byte char. A value of 0 is usually used to represent false and any nonzero value is true. We rarely use numbers to represent booleans, as C++ contains the true and false keywords. A couple of boolean variable declarations would be:
bool isTrue = true;
bool isFalse = false;
We’ve already seen in the previous section that functions can return boolean values to help create statements that make sense to a human reader:
bool numberIsNaN = isnan(nan);
Booleans will also become useful once we start looking at flow control statements in Chapter 5.
Enums
C++ allows us to create an enumerated list of values. This is useful if we wish to convey sets of things that have readable names. An example of an enum in C++ is:
enum class Color
{
Red,
Green,
Blue
};
This has effectively contained a new type in C++, Color. We can create new variables of type Color like this:
Color currentColor = Color::Red;
Using enums is a useful way to create code that is highly readable. Compare the preceding line to this:
unsigned int currentColor = 0;
This code essentially does exactly the same as the preceding line, but it is much more difficult to understand. We have no way of knowing that 0 was the color red and it was also possible to assign the number 10 to currentColor, which wouldn’t be a valid color.
Enums also allow us to assign a value to each element. In the Color enum we currently have Red assigned the value 0, Green 1 and Blue 2. In the enum definition we could have used the following:
enum class Color
{
Red,
Green = 10,
Blue
};
In the preceding enum, Red is still 0, and Green is 10; however, Blue is 11, as it directly follows Green. There are few occasions where we need to specify the values of enums as they are most useful for creating more readable code; but it is useful to understand that this is possible because you will come across code written by others that will use this feature.
It’s also important to note that the enum class is a C++11 construct. Prior to C++11 the enum would have been created using the following:
enum Color
{
Red,
Green,
Blue
};
C++11 style enums are known as strongly typed enums. The compiler will not allow you to accidentally use integers in place of the enum values. It also wouldn’t have been possible to use the value Red in two different enums.
enum Color
{
Red,
Green,
Blue,
};
enum TrafficLights
{
Red,
Amber,
Green
};
This is not allowed with older enums, as the code to define a variable would look like:
Color currentColor = Red;
TrafficLights = currentLight = Red;
As you can see, we have no way of knowing which Red is to be used. This is even worse with the Green value, as it would have a different integer representation: 1 in Color and 2 in TrafficLights. This could cause bugs in our code as it would be valid to use the TrafficLights version of Green when we really meant to use the Color version. The compiler would assume that we meant Blue as both Color::Blue and TrafficLights::Green are representations of 2. Using an enum class, however, means the code must look like this:
Color currentColor = Color::Red;
TrafficLights = currentLight = TrafficLights::Red;
As you can see, the strongly typed version of enums is much better and provides us with more explicit code. Always use an enum class where possible in new code.
Enums are the last type introduced in this chapter. We can now spend the rest of the chapter looking at the different types of operators that C++ supplies to work with our types.
Switching from One Type to Another
Sometimes while writing our programs we will have a value stored as one type, such as an int, but we would like to use the value from our variable along with a value stored in another variable. Fortunately C++ can automatically convert from some types to others. The following lines of code provide some examples:
char charNumber = 1;
int intNumber = charNumber;
float floatNumber = intNumber;
C++ can implicitly convert numbers from one type to another. Going from smaller types to larger types and from integer types to floats and floats to doubles as well as from integer types to bools are all legal and carried out automatically by the compiler.
static_cast
Whereas moving from a smaller type to