Search icon CANCEL
Subscription
0
Cart icon
Cart
Close icon
You have no products in your basket yet
Save more on your purchases!
Savings automatically calculated. No voucher code required
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
C++ Game Development Cookbook
C++ Game Development Cookbook

C++ Game Development Cookbook:

By Druhin Mukherjee
€26.99
Book May 2016 346 pages 1st Edition
eBook
€26.99
Print
€33.99
Subscription
€14.99 Monthly
eBook
€26.99
Print
€33.99
Subscription
€14.99 Monthly

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Buy Now
Table of content icon View table of contents Preview book icon Preview Book

C++ Game Development Cookbook

Chapter 1. Game Development Basics

In this chapter, the following recipes will be covered:

  • Installing an IDE on Windows

  • Choosing the right source control tool

  • Using call stacks for memory storage

  • Using recursions cautiously

  • Using pointers to store memory addresses

  • Casting between various datatypes

  • Managing memory more effectively using dynamic allocation

  • Using bitwise operations for advanced checks and optimization

Introduction


In this chapter, we will cover the basic concepts that you need to know to kick-start your career in game development.

The first step before a person starts coding is to install an integrated development environment (IDE). Nowadays, there are a few online IDEs that are available, but we are going to use an offline standalone IDE, Visual Studio. The next most important thing that many programmers do not start using at an early stage is revision control software.

Revision control software helps to back up the code in one central location; it has a historical overview of the changes that are made, which you can access and revert to if needed, and it also helps to resolve conflicts between files that have been worked on by different programmers at the same time.

The most useful feature of C++, in my opinion, is memory handling. It gives the developers a lot of control over how memory must be assigned depending on the current usage and needs of the program. As a result of this, we can allocate memory when there is a need and deallocate it accordingly.

If we do not de-allocate memory, we might run out of memory very soon, especially if we are using recursion. Sometimes there is a need to convert from one datatype to another to prevent loss of data, to pass the correct datatype in a function, and so on. C++ provides us a few ways by which we can do those castings.

The recipes in this chapter will primarily focus on these topics and deal with practical ways to implement them.

Installing an IDE on Windows


In this recipe, we will find out how easy it is to install Visual Studio on your Windows machine.

Getting ready

To go through this recipe, you will need a machine running Windows. No other prerequisites are required.

How to do it…

Visual Studio is a powerful IDE in which most professional software is written. It has loads of features and plugins to help us write better code:

  1. Go to https://www.visualstudio.com.

  2. Click on Download Visual Studio Community.

    Download Visual Studio Community

  3. This should download an .exe file.

  4. After it downloads, double-click on the setup file to start the installation.

  5. Make sure you have all the updates necessary on your Windows machine.

  6. You can also download any version of Visual Studio or Visual C++ Express.

  7. If the application asks for starting environment settings, select C++ from the available options.

Note

A few things to note are listed here:

  • You need a Microsoft account to install it.

  • There are other free IDEs for C++, such as NetBeans, Eclipse, and Code::Blocks.

  • While Visual Studio works only for Windows, Code::Blocks and other such IDEs are cross-platform and can work on Mac and Linux as well.

For the remainder of this chapter, all code examples and snippets will be provided using Visual Studio.

How it works…

An IDE is a programming environment. An IDE consists of various functionalities that can vary from one IDE to another. However, the most basic functionalities that are present in all IDEs are a code editor, a compiler, a debugger, a linker, and a GUI builder.

A code editor, or a source code editor as they are otherwise known, is useful for editing code written by programmers. They provide features such as auto-correct, syntax highlighting, bracket completion and indentation, and so on. An example snapshot of the Visual Studio code editor is shown here:

A compiler is a computer program that converts your C++ code to object code. This is necessary in order to create an executable. If you have a file called main.cpp, it will generate an object code called main.o.

A linker is a computer program that converts the object code generated by the compiler to an executable or a library file:

Compiler and linker

A debugger is a computer program that helps to test and debug computer programs.

A GUI builder helps the designer and programmer to create GUI content or widgets easily. It uses a drag and drop WYSIWYG tool editor.

Choosing the right source control tool


In this recipe, we will see how easy it is to take a backup of our code using the right version control. The advantages of having a backup to a central server is that you will never lose work, can download the code on any machine, and can also go back to any of your changes from the past. Imagine it is like a checkpoint that we have in games, and you can go back to that checkpoint if you face problems.

Getting ready

To go through this recipe, you will need a machine running Windows. No other prerequisites are required.

How to do it…

Choosing a correct version tool is very important as it will save a lot of time organizing data. There are a few versioning tools that are available, so it is very important that we should be informed about all of them so that we can use the correct one based on our needs.

First analyze the choices that are available to you. The choices primarily include Concurrent Versions System (CVS), Apache Subversion (SVN), Mercurial, and GIT.

How it works…

CVS has been around for a long time, so there is tons of documentation and help available. However, a lack of atomic operations often leads to source corruption and it is not well cut out for long-term branching operations.

SVN was made as an improvement to CVS and it does fix many of its issues relating to atomic operations and source corruption. It is free and open source. It has lots of plugins for different IDEs. However, one of the major drawbacks of this tool is that it is comparatively very slow in its operations.

GIT was made primarily for Linux but it improves operation speed a lot. It works on UNIX systems as well. It has cheap branch operations but it is not totally optimized for a single developer and its Windows support is limited compared to Linux. However, GIT is extremely popular and many prefer GIT to SVN or CVS.

Mercurial came into existence shortly after GIT. It has node-based operations but does not allow the merging of two parent branches.

So to sum up, use SVN if you want a central repository that others can push and pull. Although it has its limitations, it's easy to learn. Use Mercurial or GIT if you want a distributed model. In this case, there is a repository on every computer, and generally, one of them is regarded as the official one. Mercurial is often preferred if it is a relatively small team, and it's easier to learn than GIT.

We will look into these in more detail in a separate chapter.

Tip

Detailed steps to download the code bundle are mentioned in the Preface of this book. Please have a look.

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/C++Game-Development-Cookbook. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Using call stacks for memory storage


The main reason why C++ is still the preferred language for most game developers is that you handle memory yourself and control the allocation and de-allocation of memory to a great extent. For that reason, we need to understand the different memory spaces that are provided to us. When data is "pushed" onto the stack, the stack grows. As data is "popped" off the stack, the stack shrinks. It is not possible to pop a particular piece of data off the stack without first popping off all data placed on top of it. Think of this as a series of compartments aligned top to bottom. The top of the stack is whatever compartment the stack pointer happens to point to (this is a register).

Each compartment has a sequential address. One of those addresses is kept in the stack pointer. Everything below that magic address, known as the top of the stack, is considered to be on the stack. Everything above the top of the stack is considered to be off the stack. When data is pushed onto the stack, it is placed into a compartment above the stack pointer, and then the stack pointer is moved to the new data. When data is popped off the stack, the address of the stack pointer is changed by moving it down the stack.

Getting ready

You need to have a working copy of Visual Studio installed on your Windows machine.

How to do it...

C++ is probably one of the best programming languages out there and one of the main reasons for that is that it is also a low level language, because we can manipulate memory. To understand memory handling, it is very important to understand how memory stacks work:

  1. Open Visual Studio.

  2. Create a new C++ project.

  3. Select Win32 Console Application.

  4. Add a source file called main.cpp or anything that you want to name the source file.

  5. Add the following lines of code:

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    int countTotalBullets(int iGun1Ammo, int iGun2Ammo)
    {
        return iGun1Ammo + iGun2Ammo;
    }
    
    int main()
    {
        int iGun1Ammo = 3;
        int iGun2Ammo = 2;
        int iTotalAmmo = CountTotalBullets(iGun1Ammo, iGun2Ammo);
    
        cout << "Total ammunition currently with you is"<<iTotalAmmo;
    
        _getch();
    }

How it works…

When you call the function CountTotalBullets, the code branches to the called function. The parameters are passed in and the body of the function is executed. When the function completes, a value is returned and the control returns to the calling function.

But how does it really work from a compiler's point of view? When you begin your program, the compiler creates a stack. The stack is a special area of memory allocated for your program in order to hold the data for each function in your program. A stack is a Last In First Out (LIFO) data structure. Imagine a deck of cards; the last card put on the pile will be the first card taken out.

When your program calls CountTotalBullets, a stack frame is established. A stack frame is an area of the stack set aside to manage that function. This is very complex and different on different platforms, but these are the essential steps:

  1. The return address of CountTotalBullets is put on the stack. When the function returns, it will resume executing at this address.

  2. Room is made on the stack for the return type you have declared.

  3. All arguments to the function are placed on the stack.

  4. The program branches to your function.

  5. Local variables are pushed onto the stack as they are defined.

Using recursions cautiously


Recursions are a form of programming design in which the function calls itself multiple times to solve a problem by breaking down a large solutions set into multiple small solution sets. The code size definitely shortens. However, if not used properly, recursions can fill up the call stack really fast and you can run out of memory.

Getting ready

To get started with this recipe, you should have some prior knowledge of call stacks and how memory is assigned during a function call. You need a Windows machine with a working copy of Visual Studio.

How to do it…

In this recipe, you will see how easy it is to use recursions. Recursions are very smart to code but also can lead to some serious problems:

  1. Open Visual Studio.

  2. Create a new C++ project.

  3. Select Win32 Console Application.

  4. Add a source file called main.cpp or anything that you want to name the source file.

  5. Add the following lines of code:

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    int RecursiveFactorial(int number);
    int Factorial(int number);
    int main()
    {
        long iNumber;
        cout << "Enter the number whose factorial you want to find";
        cin >> iNumber;
    
        cout << RecursiveFactorial(iNumber) << endl;
        cout << Factorial(iNumber);
    
        _getch();
        return 0;
    }
    
    int Factorial(int number)
    {
        int iCounter = 1;
        if (number < 2)
        {
            return 1;
        }
        else
        {
            while (number>0)
            {
                iCounter = iCounter*number;
                number -= 1;
            }
    
        }
        return iCounter;
    }
    
    int RecursiveFactorial(int number)
    {
        if (number < 2)
        {
            return 1;
        }
        else
        {
            while (number>0)
        {
                return number*Factorial(number - 1);
            }
        }
    
    }

How it works…

As you can see from the preceding code, both the functions find the factorial of a number. However, when using recursion, the stack size will grow immensely with each function call; the stack pointer has to be updated every call and data pushed onto the stack. With recursion, as the function calls itself, every time a function is called from within itself the stack size will keep on rising until it runs out of memory and creates a deadlock or crashes.

Imagine finding the factorial of 1000. The function will be called within itself a very large number of times. This is a recipe for certain disaster and we should avoid such coding practices to a great extent.

There's more…

You can use a larger datatype than int if you are finding the factorial of a number greater than 15, as the resulting factorial will be too large to be stored in int.

Using pointers to store memory addresses


In the previous two recipes, we have seen how not having sufficient memory can be a problem to us. However, until now, we have had no control over how much memory is assigned and what is assigned to each memory address. Using pointers, we can address this issue. In my opinion, pointers are the single most important topic in C++. If your concept of C++ has to be clear, and if you are to become a good developer in C++, you must be good with pointers. Pointers can seem very daunting at first, but once you get the hang of it, pointers are pretty easy to use.

Getting ready

For this recipe, you will need a Windows machine with a working copy of Visual Studio.

How to do it…

In this recipe, we will see how easy it is to work with pointers. Once you are comfortable using pointers, we can manipulate memory and store references in memory quite easily:

  1. Open Visual Studio.

  2. Create a new C++ project.

  3. Select Win32 Console Application.

  4. Add a source file called main.cpp or anything that you want to name the source file.

  5. Add the following lines of code:

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    int main()
    {
        float fCurrentHealth = 10.0f;
    
        cout << "Address where the float value is stored: " << &fCurrentHealth << endl;
        cout << "Value at that address: " << *(&fCurrentHealth) << endl;
    
        float* pfLocalCurrentHealth = &fCurrentHealth;
        cout << "Value at Local pointer variable: "<<pfLocalCurrentHealth << endl;
        cout << "Address of the Local pointer variable: "<<&pfLocalCurrentHealth << endl;
        cout << "Value at the address of the Local pointer variable: "<<*pfLocalCurrentHealth << endl;
    
        _getch();
        return 0;
    }

How it works…

One of the most powerful tools of a C++ programmer is to manipulate computer memory directly. A pointer is a variable that holds a memory address. Each variable and object used in a C++ program is stored in a specific place in memory. Each memory location has a unique address. Memory addresses will vary depending on the operating system used. The amount of bytes taken up depends on the variable type: float = 4 bytes, short = 2 bytes:

Pointers and memory storage

Each location in the memory is 1 byte. The pointer pfLocalCurrentHealth holds the address of the memory location that has stored fCurrentHealth. Hence, when we display the contents of the pointer, we get the same address as that of the address containing the fCurrentHealth variable. We use the & operator to get the address of the pfLocalCurrentHealth variable. When we reference the pointer using the * operator, we get the value stored at the address. Since the stored address is same as the address storing fCurrentHealth, we get the value 10.

There's more…

Let us consider the following declarations:

  • const float* pfNumber1

  • float* const pfNumber2

  • const float* const pfNumber3

All of these declarations are valid. But what do they mean? The first declaration states that pfNumber1 is a pointer to a constant float. The second declaration states that pfNumber2 is a constant pointer to a float. The third declaration states that pfNumber3 is a constant pointer to a constant integer. The key differences between references and these three types of const pointers are listed here:

  • const pointers can be NULL

  • A reference does not have its own address, whereas a pointer does

    The address of a reference is the actual object's address

  • A pointer has its own address and it holds as its value the address of the value it points to

Casting between different datatypes


Casting is a conversion process of changing some data into a different type of data. We can convert between built-in types or our own datatypes. Some of the conversions are done automatically by the compiler, and the programmer does not have to intervene. Such conversions are called implicit conversions. Other conversions, which have to be directly specified by the programmer, are called explicit conversion. Sometimes we may get warnings about loss of data. We should pay heed to these warnings and think about how this might adversely affect our code. Casting is commonly used when the interface expects a particular type, but we want to feed it data of a different type. With C, we can cast anything to everything. However, C++ provides us with finer controls.

Getting ready

For this recipe, you will need a Windows machine with a working copy of Visual Studio.

How to do it…

In this recipe, we will see how we can easily cast or convert between various datatypes. Usually, a programmer uses C-style casting even in C++, but this is not recommended. C++ provides us with its own style of casting for different situations which we should use:

  1. Open Visual Studio.

  2. Create a new C++ project.

  3. Select Win32 Console Application.

  4. Add a source file called main.cpp or anything that you want to name the source file.

  5. Add the following lines of code:

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    int main()
    {
        int iNumber = 5;
        int iOurNumber;
        float fNumber;
    
        //No casting. C++ implicitly converts the result into an int and saves 
        //into a float
        fNumber = iNumber/2;
        cout << "Number is " << fNumber<<endl;
    
        //C-style casting. Not recommended as this is not type safe
        fNumber = (float)iNumber / 2;
        cout << "Number is " << fNumber<<endl;
    
        //C++ style casting. This has valid constructors to make the casting a safe one
        iOurNumber = static_cast<int>(fNumber);
        cout << "Number is " << iOurNumber << endl;
    
        _getch();
        return 0;
    }

How it works…

There are four types of casting operators in C++, depending on what we are casting: static_cast, const_cast, reinterpret_cast, and dynamic_cast. Now, we are going to look at static_cast. We will look at the remaining three casting technique after we discuss dynamic memory and classes. Converting from a smaller datatype to a larger type is called promotion and is guaranteed to have no data loss. However, conversion from a larger datatype to a smaller one is called demotion and may lead to data loss. Compilers will generally give you a warning when this happens, and you should pay heed to this.

Let us look at the previous example. We have initialized an integer with the value 5. Next, we have initialized a floating point variable and stored the result of 5 divided by 2, which is 2.5. However, when we display the variable fNumber, we see that the displayed value is 2. The reason is the C++ compiler implicitly casts the result of 5/2 and stores it as an integer. So it is evaluating something similar to int (5/2) which is int (2.5), evaluating to 2. So to achieve our desired result, we have two options. The first method is a C-style explicit cast, which is not recommended at all because it does not have a type safe check. The format for the C-style cast is (resultant_data_type) (expression), which in this case is something like float (5/2). We are explicitly telling the compiler to store the result of the expression as a floating point number. The second method, and a more C++ style way of doing the cast, is by using the static_cast operation. This has suitable constructors to dictate that the conversion is type safe. The format for a static_cast operation is static_cast<resultant_data_type> (expression). The compiler checks if the casting conversion is safe and then executes the type casting operation.

Managing memory more effectively using dynamic allocation


Programmers generally deal with five areas of memory: global namespace, registers, code space, stack, and the free store. When an array is initialized, the number of elements has to be defined. This leads to lots of memory problems. Most of the time, not all elements that we allocated are used, and sometimes we need more elements. To help overcome this problem, C++ facilitates memory allocation while an .exe file is running by using the free store.

The free store is a large area of memory that can be used to store data, and is sometimes referred to as the heap. We can request some space on the free store, and it will give us an address that we can use to store data. We need to keep that address in a pointer. The free store is not cleaned up until your program ends. It is the programmer's responsibility to free any free store memory used by their program.

The advantage of the free store is that there is no need to preallocate all variables. We can decide at runtime when more memory is needed. The memory is reserved and remains available until it is explicitly freed. If memory is reserved while in a function, it is still available when control returns from that function. This is a much better way of coding than global variables. Only functions that have access to the pointer can access the data stored in memory, and it provides a tightly controlled interface to that data.

Getting ready

For this recipe, you will need a Windows machine with a working copy of Visual Studio.

How to do it…

In this recipe, we will see how easy it is to use dynamic allocation. In games, most of the memory is allocated dynamically at runtime as we are never sure how much memory we should assign. Assigning an arbitrary amount of memory may result in less memory or memory wastage:

  1. Open Visual Studio.

  2. Create a new C++ project.

  3. Add a source file called main.cpp or anything that you want to name the source file.

  4. Add the following lines of code:

    #include <iostream>
    #include <conio.h>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    
      int iNumberofGuns, iCounter;
      string * sNameOfGuns;
      cout << "How many guns would you like to purchase? ";
      cin >> iNumberofGuns;
      sNameOfGuns = new string[iNumberofGuns];
      if (sNameOfGuns == nullptr)
        cout << "Error: memory could not be allocated";
      else
      {
        for (iCounter = 0; iCounter<iNumberofGuns; iCounter++)
        {
          cout << "Enter name of the gun: ";
          cin >> sNameOfGuns[iCounter];
        }
        cout << "You have purchased: ";
        for (iCounter = 0; iCounter<iNumberofGuns; iCounter++)
          cout << sNameOfGuns[iCounter] << ", ";
        delete[] sNameOfGuns;
      }
    
      _getch();
      return 0;
    }

How it works…

You can allocate memory to the free store using the new keyword; new is followed by the type of the variable you want to allocate. This allows the compiler to know how much memory will need to be allocated. In our example, we have used string. The new keyword returns a memory address. This memory address is assigned to a pointer, sNameOfGuns. We must assign the address to a pointer, otherwise the address will be lost. The format for using the new operator is datatype * pointer = new datatype. So in our example, we have used sNameOfGuns = new string[iNumberofGuns]. If the new allocation fails, it will return a null pointer. We should always check whether the pointer allocation has been successful; otherwise we will try to access a part of the memory that has not been allocated and we may get an error from the compiler, as shown in the following screenshot, and your application will crash:

When you are finished with the memory, you must call delete on the pointer. Delete returns the memory to the free store. Remember that the pointer is a local variable. Where the function that the pointer is declared in goes out of scope, the memory on the free store is not automatically deallocated. The main difference between static and dynamic memory is that the creation/deletion of static memory is handled automatically, whereas dynamic memory must be created and destroyed by the programmer.

The delete[] operator signals to the compiler that it needs to free an array. If you leave the brackets off, only the first element in the array will be deleted. This will create a memory leak. Memory leaks are really bad as it means there are memory spaces that have not been deallocated. Remember, memory is a finite space, so eventually you are going to run into trouble.

When we use delete[], how does the compiler know that it has to free n number of strings from the memory? The runtime system stores the number of items somewhere it can be retrieved only if you know the pointer sNameOfGuns. There are two popular techniques that do this. Both of these are used by commercial compilers, both have tradeoffs, and neither are perfect:

  • Technique 1:

    Over-allocate the array and put the number of items just to the left of the first element. This is the faster of the two techniques, but is more sensitive to the problem of the programmer saying delete sNameOfGuns, instead of delete[] sNameOfGuns.

  • Technique 2:

    Use an associative array with the pointer as a key and the number of items as the value. This is the slower of the two techniques, but is less sensitive to the problem of the programmer saying delete sNameOfGuns, instead of delete[] sNameOfGuns.

There's more…

We can also use a tool called VLD to check for memory leaks.

Note

Download VLD from https://vld.codeplex.com/.

After the setup has downloaded, install VLD on your system. This may or may not set up the VC++ directories correctly. If it doesn't, do it manually by right-clicking on the project page and adding the directory of VLD to the field called Include Directories, as shown in the following figure:

After setting up the directories, add the header file <vld.h> in your source file. After you execute your application and exit it, your output window will now show whether there are any memory leaks in your application.

Understanding the error messages

When using the debug build, you may notice the following values in memory during debugging:

  • 0xCCCCCCCC: This refers to values being allocated on the stack, but not yet initialized.

  • 0xCDCDCDCD: This means memory has been allocated in the heap, but it is not yet initialized (clean memory).

  • 0xDDDDDDDD: This means memory has been released from the heap (dead memory).

  • 0xFEEEFEEE: This refers to values being deallocated from the free store.

  • 0xFDFDFDFD: "No man's land" fences, which are placed at the boundary of heap memory in debug mode. These should never be overwritten, and if they are, it probably means the program is trying to access memory at an index outside of an array's max size.

Using bitwise operations for advanced checks and optimization


In most cases, a programmer will not need to worry too much about bits unless there is a need to write some compression algorithms, and when we are making a game, we never know when a situation such as that arises. In order to encode and decode files compressed in this manner, you need to actually extract data at the bit level. Finally, you can use bit operations to speed up your program or perform neat tricks. However, this is not always recommended.

Getting ready

For this recipe, you will need a Windows machine with a working copy of Visual Studio.

How to do it…

In this recipe, we will see how easy it is to use bitwise operations to perform operations by manipulating memory. Bitwise operations are also a great way to optimize code by directly interacting with memory:

  1. Open Visual Studio.

  2. Create a new C++ project.

  3. Add a source file called main.cpp or anything that you want to name the source file.

  4. Add the following lines of code:

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    void Multi_By_Power_2(int iNumber, int iPower);
    void BitwiseAnd(int iNumber, int iNumber2);
    void BitwiseOr(int iNumber, int iNumber2);
    void Complement(int iNumber4);
    void BitwiseXOR(int iNumber,int iNumber2);
    
    int main()
    {
      int iNumber = 4, iNumber2 = 3;
      int iPower = 2;
      unsigned int iNumber4 = 8;
    
      Multi_By_Power_2(iNumber, iPower);
      BitwiseAnd(iNumber,iNumber2);
      BitwiseOr(iNumber, iNumber2);
      BitwiseXOR(iNumber,iNumber2);
      Complement(iNumber4);
    
      _getch();
      return 0;
    }
    
    void Multi_By_Power_2(int iNumber, int iPower)
    {
      cout << "Result is :" << (iNumber << iPower)<<endl;
    }
    void BitwiseAnd(int iNumber, int iNumber2)
    {
      cout << "Result is :" << (iNumber & iNumber2) << endl;
    }
    void BitwiseOr(int iNumber, int iNumber2)
    {
      cout << "Result is :" << (iNumber | iNumber2) << endl;
    }
    void Complement(int iNumber4)
    {
      cout << "Result is :" << ~iNumber4 << endl;
    }
    void BitwiseXOR(int iNumber,int iNumber2)
    {
      cout << "Result is :" << (iNumber^iNumber2) << endl;
    }

How it works…

The left shift operator is the equivalent of moving all the bits of a number a specified number of places to the left. In our example, the numbers we are sending to the function Multi_By_Power_2 is 4 and 3. The binary representation of 4 is 100, so if we shift the most significant bit, which is 1, three places to the left, we get 10000, which is the binary of 16. Hence, left shift is equivalent to integer division by 2^shift_arg, that is, 4*2^3, which is again 16. Similarly, the right shift operation is equivalent to integer division by 2^shift_arg.

Now let us consider we want to pack data so that the data is compressed. Consider the following example:

int totalammo,type,rounds;

We are storing the total bullets in a gun; the type of gun, but it can only be a rifle or pistol; and the total bullets per round it can fire. Currently we are using three integer values to store the data. However, we can compress all the preceding data into one single integer and hence compress the data:

int packaged_data;
packaged_data = (totalammo << 8) | (type << 7) | rounds;

If we assume the following notations:

  • TotalAmmon: A

  • Type: T

  • Rounds: R

The final representation in the data would be something like this:

AAAAAAATRRRRRRR
Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Level up your game programming skills with insightful recipes on building games in C++
  • Analyze the less commonly discussed problems with C++ applications to develop the best games
  • Improve the performance of your games with the new multi-threading and networking features of C++11

Description

C++ is one of the preferred languages for game development as it supports a variety of coding styles that provides low-level access to the system. C++ is still used as a preferred game programming language by many as it gives game programmers control of the entire architecture, including memory patterns and usage. However, there is little information available on how to harness the advanced features of C++ to build robust games. This book will teach you techniques to develop logic and game code using C++. The primary goal of this book is to teach you to create high-quality games using C++ game programming scripts and techniques, regardless of the library or game engine you use. It will show you how to make use of the object-oriented capabilities of C++ so you can write well-structured and powerful games of any genre. The book also explores important areas such as physics programming and audio programming, and gives you other useful tips and tricks to improve your code. By the end of this book, you will be competent in game programming using C++, and will be able to develop your own games in C++.

What you will learn

[*] Explore the basics of game development to build great and effective features for your game [*] Develop your first text-based game using the various concepts of object-oriented programming [*] Use algorithms when developing games with various sorting and searching techniques [*] Exploit data structures in a game's development for data storage [*] Create your first 2D game using GDI library and sprite sheet. [*] Build your first advanced 2D game of space invaders using patterns such as observer, fly-weight, abstract factory, command, state, and more

Product Details

Country selected

Publication date : May 30, 2016
Length 346 pages
Edition : 1st Edition
Language : English
ISBN-13 : 9781785882722
Vendor :
Microsoft
Category :
Concepts :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Buy Now

Product Details


Publication date : May 30, 2016
Length 346 pages
Edition : 1st Edition
Language : English
ISBN-13 : 9781785882722
Vendor :
Microsoft
Category :
Concepts :

Table of Contents

20 Chapters
C++ Game Development Cookbook Chevron down icon Chevron up icon
Credits Chevron down icon Chevron up icon
About the Author Chevron down icon Chevron up icon
About the Reviewer Chevron down icon Chevron up icon
www.PacktPub.com Chevron down icon Chevron up icon
Preface Chevron down icon Chevron up icon
1. Game Development Basics Chevron down icon Chevron up icon
2. Object-Oriented Approach and Design in Games Chevron down icon Chevron up icon
3. Data Structures in Game Development Chevron down icon Chevron up icon
4. Algorithms for Game Development Chevron down icon Chevron up icon
5. Event-Driven Programming – Making Your First 2D Game Chevron down icon Chevron up icon
6. Design Patterns for Game Development Chevron down icon Chevron up icon
7. Organizing and Backing Up Chevron down icon Chevron up icon
8. AI in Game Development Chevron down icon Chevron up icon
9. Physics in Game Development Chevron down icon Chevron up icon
10. Multithreading in Game Development Chevron down icon Chevron up icon
11. Networking in Game Development Chevron down icon Chevron up icon
12. Audio in Game Development Chevron down icon Chevron up icon
13. Tips and Tricks Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Empty star icon Empty star icon Empty star icon Empty star icon Empty star icon 0
(0 Ratings)
5 star 0%
4 star 0%
3 star 0%
2 star 0%
1 star 0%
Top Reviews
No reviews found
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.