C++ variables
Variables are the way that our C++ games store and manipulate values. If we want to know how much health the player has then we need a variable. Perhaps you want to know how many zombies are left in the current wave? That is a variable as well. If you need to remember the name of the player who got a particular high score, you guessed it, we need a variable for that. Is the game over or still playing? Yep, that's a variable too.
Variables are named identifiers to locations in memory. So we might name a variable numberOfZombies
and that variable could refer to a place in the memory that stores a value representing the number of zombies that are left in the current wave.
The way that computer systems address locations in memory is complex. Programming languages use variables to give a human-friendly way to manage our data in memory.
Our brief discussion about variables implies that there must be different types of variable.
Types of variable
There are a wide variety of C++ variable types (see the next tip about variables). It would easily be possible to spend an entire chapter discussing them. What follows is a table of the most commonly used types in this book. Then we will look at how to actually use each of these variable types.
The compiler must be told what type a variable is, so that it can allocate the right amount of memory for it. It is good practice to use the best and most appropriate type for each and every variable you use. In practice, however, you will often get away with promoting a variable. Perhaps you need a floating-point number with just five significant digits? The compiler won't complain if you store it as a double
. However, if you try to store a float
or a double
in an int
, it will change/cast the value to fit the int
. As we progress through the book, I clarify what is the best variable type to use in each case, and we will even see a few instances where we deliberately convert/cast between variable types.
A few extra details worth noticing, in the table above, include the f
postfix next to all the float
values. This f
tells the compiler that the value is a float
type not a double
. A floating-point value without the f
prefix is assumed to be a double
. See the next tip about variables for more about this.
As mentioned previously, there are many more types. If you want to find out more about types see the next tip about variables.
Constants
Sometimes we need to make sure that a value can never be changed. To achieve this we can declare and initialize a constant using the const
keyword:
const float PI = 3.141f; const int PLANETS_IN_SOLAR_SYSTEM = 8; const int NUMBER_OF_ENEMIES = 2000;
It is conventional to declare constants in all upper case. The value of the preceding constants can never be altered. We will see some constants in action in Chapter 4: Loops, Arrays, Switch, Enumerations, and Functions - Implementing Game Mechanics.
User-defined types
User-defined types are way more advanced than the types we have just seen. When we talk about user-defined types in C++ we are usually talking about classes. We briefly talked about classes and their related objects in the previous chapter. We can write code in a separate file, sometimes in two separate files. From these we will then be able to declare, initialize, and use them. We will leave how we define/create our own types until Chapter 6: Object-Oriented Programming, Classes, and SFML Views.
Declaring and initializing variables
So far we know that variables are for storing the data/values that our games need in order to work. For example, a variable could represent the number of lives a player has or the player's name. We also know that there is a wide selection of different types of values that these variables can represent, such as int
, float
, bool
, and so on. Of course what we haven't seen yet is how we would actually go about using a variable.
There are two stages for creating and preparing a new variable. The stages are called declaration and initialization.
Declaring variables
We can declare variables in C++ like this:
// What is the player's score? int playerScore; // What is the players first initial char playerInitial; // What is the value of pi float valuePi; // Is the player alive or dead? bool isAlive;
Initializing variables
Now we have declared the variables with meaningful names, we can initialize those same variables with appropriate values, like this:
playerScore = 0; playerInitial = 'J'; valuePi = 3.141f; isAlive = true;
Declaring and initializing in one step
When it suits us, we can combine the declaration and initialization steps into one:
int playerScore = 0; char playerInitial = 'J'; float valuePi = 3.141f; bool isAlive = true;
Tip
Variables tipAs promised, here is the tip on variables. If you want to see a complete list of C++ types then check this web page: http://www.tutorialspoint.com/cplusplus/cpp_data_types.htm. If you want a deeper discussion on floats, doubles, and the f
postfix then read this: http://www.cplusplus.com/forum/beginner/24483/. And if you want to know the ins and out of ASCII character codes then there is some more information here: http://www.cplusplus.com/doc/ascii/. Note that these links are for the curious reader and we have already discussed enough in order to proceed.
Declaring and initializing user-defined types
We have already seen examples of how we declare and initialize some SFML defined types. Because the way we can create/define these types (classes) is so flexible, the way we declare and initialize them is also highly varied. Here are a couple of reminders for declaring and initializing user-defined types, from the previous chapter.
Create an object of type VideoMode
, called vm
, and initialize it with two int
values, 1920
and 1080
:
// Create a video mode object VideoMode vm(1920, 1080);
Create an object of type Texture
, called textureBackground
but don't do any initialization:
// Create a texture to hold a graphic on the GPU Texture textureBackground;
Note that it is possible (in fact very likely) that even though we are not suggesting any specific values with which to initialize textureBackground
, some variables may be set up internally. Whether or not an object needs/has the option of giving initialization values at this point is entirely dependent on how the class is coded and is almost infinitely flexible. This further suggests that when we get to write our own classes there will be some complexity. Fortunately, it also means we will have significant power to design our types/classes, so they are just what we need to make our games! Add this huge flexibility to SFML-designed classes and the potential for our games is almost limitless.
We will see a few more user-created types/classes provided by SFML in this chapter too and loads more throughout the book.