Exploring the Use of C++ for Game Development

What to Consider When Developing a Video Game

To make a video game of your own, you’ll need a fun idea for a game, which is a big hurdle to overcome to start making a game. Let’s assume you have an idea for a game and want to bring it to life. To do this, you’ll need to write code to make everything work, art and sound design to make everything appealing, and you’ll need to do anything you can to ensure your game runs smoothly and the experience is enjoyable for your user.

The last piece of the puzzle of making the game run smoothly is the priority for many game developers, and choosing the correct language to code your game typically ties back to this issue. C++ is “renowned for its speed and flexibility, and [its] ability to communicate directly with hardware.” [1] Before jumping into the details of why C++ works so efficiently, let’s explore a few other languages used for game development and where they may have an edge over C++.

Comparing C++ With Other Game Development Languages

Before discussing C#(Sharp) and Java, I want to highlight a few other languages used in game development for different reasons.

JavaScript, Python, and Lua

JavaScript can be found on web pages, servers, and even on Raspberry Pis, which has become a popular way to make portable game systems. A few game engines support JavaScript code, including “Impact.js, LÖVE, and Crafty.js.” [2] Python and Lua can be easier to pick up when learning a new programming language, and both come with support from many open-source game engines. These three languages have been mainly used for 2D games. They can also be used with 3D games, but it is recommended to use Python for 3D over the other two since JavaScript has limited support and Lua has no support. In a future article, I plan to spend more time researching these languages in the gaming space.

C#(Sharp)

C# has support from many game engines, which include Unity and MonoGame. C# is similar to C++, and it is reported to be “less complicated and easier to set up with Visual Studio and VS Code as your Integrated Development Environment.” [2] There are many differences between C++ and C# as well, and they should be considered when deciding on the language you’ll use. We’re going to highlight a couple differences [3]:

Memory Management

In C++, the programmer manually manages memory, while C# has an automatic garbage collector. C# is more convenient for this task, but C++ gives the programmer more control over how the memory is used, which can lead to optimizing code to run more quickly for smoother performance. Depending on the size of the project, this amount of control over memory may not be necessary if the project is small.

Pointers

Pointers are a way of referencing an address in memory, and I will go into more detail later in the article. In C++, pointers can be used anywhere in the program, while C# can only use pointers in unsafe mode. “Unsafe code can create issues with stability and security due to its inherent complex syntax and potential for memory-related errors, such as stack overflow, accessing and overwriting system memory.” [4] This means that extra special care needs to used with the unsafe mode in C#, which means that pointers may need to be avoided when writing code for your project.

Java

Java is an object-oriented programming language similar to C++, and “the Java Virtual Machine (JVM) is used to run the bytecode, which makes it compatible with almost any platform.” [2] The differences between Java and C++ are similar to C# and let’s explore why [5]:

Memory Management

In Java, memory management is controlled by the Java Virtual Machine (JVM), while C++ is manually controlled.

Platform Dependency

Both languages work on any platform. For Java, it uses the Java Virtual Machine (JVM) to accomplish this. For C++, it needs the correct compiler to compile the code for the correct platform.

Pointers

Java can use pointers, but there is limited support for them. C++ fully embraces pointers to the point that values can also be called by reference, and Java only calls by value for the pointers.

Choosing C++ For Video Game Development

When developing a video game, resuing assets will happen naturally. Introducing obstacles for your player to overcome and returning to the same or similar obstacle later creates a sense of progression for your player to show them how they have grown throughout the experience or how they can look at an obstacle in different ways to overcome it. This structure sounds like a class in programming, a way to reuse code multiple times throughout an application. Picking an object-oriented programming language will be paramount for a smoother development period. Luckily, the languages I’ve mentioned all support class-based programming techniques. Let’s look into why C++ is often chosen for game projects.

Regarding performance, video games designed with C++ run more quickly and smoothly than other languages when creating games that can scale well. C++ accomplishes this by giving the programmer direct control over memory management. Other languages handle these tasks automatically with garbage collectors. “Understanding pointers, memory allocation, and memory leaks can help your game run smoothly without wasting valuable resources.” [1] We’re going to break down these three things with a few coding examples.

Pointers

A pointer is a variable that stores the memory address as its value. Since a pointer stores an address, we can make a call-by-reference. Pointers can “create and manipulate dynamic data structures” [6] and can be used to iterate over these data structures.

To use a pointer, you need to define a pointer variable that matches the data type you will be referencing. The data type must be associated with a pointer so it “knows how many bytes the data is stored in.” [6] Use the unary operator & on the variable address you want to store on the previously created pointer. To access the value stored at an address, use the unary operator * on the pointer.

#include <bits/stdc++.h>
using namespace std;

void pointers() {
    int var = 20;

    // Declare pointer variable
    // Note that the data type of ptr and var must be the same
    int* ptr;

    // Declare pointer of a pointer variable
    int** ptr2;

    // Assign the address of a variable to a pointer
    ptr = &var;

    // Assign the address of a pointer to another pointer
    ptr2 = &ptr;


    // ptr holds the address of var
    cout << "Value at ptr = " << ptr << endl;

    // var holds the value of 20
    cout << "Value at var = " << var << endl;

    // * dereferences ptr to give the value of 20 
      // located at the address assigned to ptr
    cout << "Value at *ptr = " << *ptr << endl;

    // ptr2 holds the address of ptr
    // Even pointers have addresses of their own
    cout << "Value at ptr2 = " << ptr2 << endl;

    // Dereferencing ptr2 once reveals that 
      // ptr2 references the same address as ptr
    cout << "Value at *ptr2 = " << *ptr2 << endl;

    // Dereferencing ptr2 twice reveals 20, 
      // the value you receive when dereferencing ptr once
    cout << "Value at **ptr2 = " << **ptr2 << endl;
}

int main() {
    pointers();
    /*
     * Value at ptr = 0x6caebffc54
     * Value at var = 20
     * Value at *ptr = 20
     * Value at ptr2 = 0x6caebffc48
     * Value at *ptr2 = 0x6caebffc54
     * Value at **ptr2 = 20
     */
    return 0;
}

Enter fullscreen mode Exit fullscreen mode

Since we store the address to other data types, we simulate calling by reference. We can modify any data type within a function and reuse that updated data later in our code.

Dynamic Memory Allocation

If we expect a certain maximum-sized input, we could prepare our program to have enough memory set aside to match the worst-case scenario. This could pose a problem as a project continues to scale larger and larger. What if we could pick how much memory we need only once we know how much is needed? This would prevent unneeded memory usage and allow our code to run more efficiently. This is the key principle behind dynamic memory allocation: only set aside enough memory space to accomplish the task at hand and then free up the space immediately after.

Check out the following code [7] with the addition of comments to help you see how we accomplish dynamic memory allocation:

#include <iostream>
#include <new>
using namespace std;

int main() {
    // i => Used for looping
    int i;
    // n => Used for capturing the input for the first question
    int n;
    // ptr => Pointer used to reference memory that is allocated
    int* ptr;

    // n is assigned the input from the user
    cout << "How many numbers would you like to type? ";
    cin >> n;

    // new => Allocates space match the input for n
    ptr = new (nothrow) int[n];

    // Check to make sure ptr points to a valid object
    if (ptr == nullptr) {
        cout << "Memory allocation error!" << endl;
    }

    else {
        for (i=0; i<n; i++) {
            // Ask for a number n times
            cout << "Enter number: ";

            // Store the number entered in memory
            cin >> ptr[i];
        }

        // Reveal to the user the choices they made
        cout << "You have entered: ";

        for (i=0; i<n; i++) {
            // Pull each number from the allocated memory
            cout << ptr[i] << ", ";
        }

        // After we finish with the task,
            // we free up the space taken using delete[]
        delete[] ptr;
    }
    return 0;
}

Enter fullscreen mode Exit fullscreen mode

Output:

The use of the delete keyword is essential when coding in C++. Since programmers need to clear out their memory manually, developing good habits to clear out memory once it’s finished being used will lead to less frustration and fewer bugs, and it avoids the dreaded Memory Leak.

Memory Leak

In C++, there is no automatic garbage collection, which means that any memory that a programmer dynamically allocates throughout the lifetime of a program needs to be freed manually after its usage by the programmer once it is no longer needed. If a programmer forgets to free this memory after its usage, it will occupy the space while the program lives and will be unavailable to other processes. Often, a function may need to be called several times, and if each call allocates more memory without removing it, a lot of unused memory will take up space. This accumulation of unwanted memory usage is referred to as a memory leak. These can drastically slow down a program, but they are the avoidable price for faster running code. [8]

Final Thoughts on C++ For Game Development

Having complete control over memory usage is a huge plus, or some might call it a “plus-plus.” We create pointers to store the addresses of newly created data structures. After the stored memory has been used to completion, we remove the data from memory to free up space later in the program to prevent memory leaks. The object-oriented programming language aspect of C++ also shows the usefulness of reusing code.

C++ isn’t the only choice for a game development language. Java is portable and can be used across multiple platforms, but it is limited in making 3D games. C#(Sharp) is less complicated than C++, but it has little to no support for pointers unless you use unsafe mode, which is not recommended unless you take extreme care while programming in that mode.

Due to the programmer’s direct control of memory in C++, fast speeds can be achieved with pointers and dynamic memory allocation. Speed is an important consideration when designing a large-scale video game because an unresponsive or slow-to-respond gaming experience can leave your user unsatisfied.

Happy Coding,
Tyler Meyer

Sources

Sources:
[1] https://www.geeksforgeeks.org/cpp-for-game-development/

[2] https://www.orientsoftware.com/blog/gaming-programming-language/

[3] https://www.geeksforgeeks.org/c-vs-c-sharp/

[4] https://www.c-sharpcorner.com/UploadFile/f0b2ed/understanding-unsafe-code-in-C-Sharp/

[5] https://www.geeksforgeeks.org/cpp-vs-java/

[6] https://www.geeksforgeeks.org/cpp-pointers/

[7] https://cplusplus.com/doc/tutorial/dynamic/

[8] https://www.geeksforgeeks.org/memory-leak-in-c-and-how-to-avoid-it/

原文链接:Exploring the Use of C++ for Game Development

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容