Despite its awesome success as a hobby system, the Raspberry Pi is seldom looked on as a machine that lets you write or play your own graphical games. There are emulators, of course, and those are a great introduction to the style of retro games most old-school coders cut their teeth on as spotty youths. However, you don’t see many original games written for the Pi, on the Pi, by Pi coders. Let’s try to change that.
Game coding, on Raspberry Pi, in a professional language like C/C++ isn’t apparently very popular, but why? The Pi is more than capable of doing cool graphics, has (nearly) all the tools needed on board, and just enough horsepower to easily create and run high-octane 2D games. It can even push a decent amount of polys around to create some quite exciting 3D experiences.
There’s simply no reason not to write cool games on the Pi, so it’s time we addressed this and introduce some new Pi coders to C++ and game coding, as well as a little dabble with the Broadcom GPU.
Let’s start with the first thing all new coders need to know, which is: DON’T PANIC! C/C++ isn’t as hard as people tend to think it is, especially if we stick to core principles and concepts. It can get very complex very fast, but you can take your time and make progress at your own rate and still create cool things.
But before we can use the language, we really need to have a development system known as an integrated development environment, or IDE for short; this contains all our code and lets us edit, build, and debug our code in one program. Of course, you can use multiple files and command-line systems, but IDEs are designed to make things easier, so let’s just use them.
For this set of tutorials we’re going to use Code::Blocks, which you can find using sudo apt‑get install codeblocks in your Terminal window.
Code::Blocks gives us access to a much more C++ friendly editor, compiler and debugger, and lets us run our code directly from the edit screen. Once installed, it appears in Programming tools (see pic below).
First steps
Coders always start learning with the Hello World example, so we should do the same just to get used to our system.
Setting up a new project as a C++ Console App will produce a very simple single-file project. You can find the main.cpp file in the Sources filter on the left of your IDE screen; open up Sources and double-click on main.cpp to have a look at the file – it’s only ten lines long.
Main.cpp should be fairly understandable to a novice. There is a function, called main, and between its { and } brackets are two lines of code, one of which outputs some text; the other tells the function to return to where it was called, in this case from the command line, ending the program. The using namespace will be explained later, but it’s a way for C++ to understand that the cout function, used to print text, lives in its ‘internal’ standard libraries.
To make the program run we have two options: the green RUN arrow, or the Red Debug Arrow at the top of the Code::Blocks window. Press one; whichever you choose, you will find our project unsurprisingly prints ‘Hello World’ in what is called a console window, the black screen which pops up when our project starts. The console is very useful since it can allow us to output text to it and let us know what our project is doing at different points.
Alter the "Hello World" text in the main.cpp, so long as the text is enclosed in " " marks, you can pretty much enter anything you like, you can even repeat the line a few times to add a few more choice text quips. Go on, make it swear at someone, you know you want to.
Now that we have our project running, let’s see what Code::Blocks lets us do. Try left-clicking just after the number 7 on line 7 – a small red dot should appear (see below); you can also right-click to get more choices. This red dot represents a break point: when our code is being debugged, it will stop. Run the project again, but using the red DEBUG arrow, which will force our project to compile and run in debug mode. It will stop at the red dot, waiting for us to tell it to either continue or to step through the code using the icons next to the red arrow, which provide different step options for the code. More on that later, though. Code::Blocks gives a wide range of tools and functions to help us debug, but if this is your first time running it, not all of them will be visible – we will make them visible as our needs and experience increase.
Time for bigger steps
So, ‘Hello World’ is hardly the pinnacle of coding, but you’ve compiled and run your first project; it’s text only, but it’s our text and we love it. We might not be doing much, but we do know our tools work. Time to take things up a notch.
C/C++ works by using code it already has, known as the standard libraries, and code that you write to make use of those libraries. There are other libraries we can use or even create ourselves, but one important thing to consider is that the main() function is the starting point of any C/C++ project.
We could add hundreds of lines of code to our main() function to make it do something, but that’s not really how C++ works. In fact, that’s more how C works, because this main function is in fact a small bit of C code, which brings us to why we persist in saying C/C++.
C++ is an enhancement to C, but inside C++ there are still all the original C commands and concepts which we are free to use if we want to; it’s just that as C++ has become more and more stable and effective, we seldom rely on pure C any more, except to start up our project.
C++ can mimic C all day long, but it would deny us the chance to make use of C++’s greatest trick: OOP, or object-oriented programming.
What is OOP?
OOP can be tricky to grasp straight away, but it’s best to think of it as a means to define a ‘thing’ that does ‘something’, at the request of other ‘things’.
We usually call these things objects, and we define them in concepts called classes. A class is C++’s way of describing something as a collection of functions and data which are usually personal to any individual instance of that class. Objects can be literally anything, and such a broad idea is where people tend to get stuck.
We can create things, or classes, using a simple header file to define that class. We should start with a base class called Game, which is going to be our controlling class. We can let the main() function do a little setting up, but the sooner we leave it behind the better.
Our Game class will be responsible for controlling all the other objects in our project, some of which will themselves have objects to control. But Game is the big cheese and its job is going to be to create and initialise the objects, control the calling of updates of those objects, and then to output or return the results of their efforts somewhere. Finally, when our project has run its course, it needs to return back to the main function, to let the program shut down.
That’s a lot to take in, so let’s just try a simple bit of code to see how that works.
Starting with C++
Almost all classes have a header file that’s unique to the class; check out Game.h, in the GitHub repo.
We’ve defined the Game class as having three methods, two of which are standard, and one is something we will use to update all the systems it has.
If we now look at how our new main function sets up a Game class, seen in main.cpp, just replace all the old code that was in Hello World.
Main() now has an instance of a Game class; we use a special function called a constructor to set up some default variables, or not, as needed. Once main() creates a Game class, we then effectively pass the program control to Game and its Update() method – we’ll only return to main() when we are done and want to exit back to the OS. Of course, at the moment, the actual code for Game has not been written; let’s discuss that next.
Now that our main function has passed control of our program to Game, it’s up to Game to give us some ‘things’ to play with. Let’s create some simple objects, called SimpleObj. Like the Game class, we define these in a header file, preferably using the same name as the class we define, SimpleObj.h.
Ready to run
These are just definitions at the moment; the header contains info on what the class is and what it contains. This SimpleObj has very little code; it has the constructor/destructor methods, which we’ll discuss next time. More useful is the fact it also has a method called Update() and a function called Draw(), which currently does nothing; we’ll add that soon. It has some variables, notably a string called m_MyName, but that’s empty when it is first created.
Now that we have the definition of a SimpleObj class, we need to write the actual code, this time not in a header but in a CPP file. So, create a file called SimpleObj.cpp and then the Game.cpp file (pic below) and enter the code from the file in the GitHub repo – you could download this code, but it’s better if you type it in and get used to making and fixing typos.
So far so good
We have code for Game and SimpleObj, so we should be able to compile this on our IDE. When next we run the code, Game has two new instances of SimpleObj – they’re rather boring and dull, but they are there, and we include calls to their update() functions in the Game class’s main loop. They will be processed and print out little individual messages using their names to let you know they are there (pic below).
So, two unique instances of SimpleObj are being updated by Game.Update(), both defined by the same class definition, but unique instances with their own names. Try adding a third and see what happens.
For now, that’s as much as we can squeeze into this format, but next time we will expand our code to start working with graphics and the famous ‘hello triangle’ code that absolutely no one uses except game coders.