Discover millions of ebooks, audiobooks, and so much more with a free trial

From $11.99/month after trial. Cancel anytime.

Learn C++ for Game Development
Learn C++ for Game Development
Learn C++ for Game Development
Ebook511 pages4 hours

Learn C++ for Game Development

Rating: 0 out of 5 stars

()

Read preview

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.

LanguageEnglish
PublisherApress
Release dateJun 30, 2014
ISBN9781430264583
Learn C++ for Game Development

Read more from Bruce Sutherland

Related to Learn C++ for Game Development

Related ebooks

Software Development & Engineering For You

View More

Related articles

Reviews for Learn C++ for Game Development

Rating: 0 out of 5 stars
0 ratings

0 ratings0 reviews

What did you think?

Tap to rate

Review must be at least 10 words

    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

    Enjoying the preview?
    Page 1 of 1