Building a simple game engine in C++ (2023)

In this tutorial project, we will build a fully working and functional but simple C++ game engine. All that the game engine will do is allow the player to control one object moving left and right on a background, however, once you have completed the project you will be able to use the example game object class, Bob as a blueprint for adding as many other objects as you like. The tutorial won’t cover collision detection as that was discussed in the pong game and once you have read that tutorial it would be trivial to add this feature into the update function that we will be writing. Note that this really is a “simple” engine and future tutorials will expand and evolve this code to add more features. The long-term shortcomings of the engine are discussed at the end. What you do get with this simple game engine is a level of abstraction that will allow you to build a relatively complex game, without ending up in a tangled mess of code.
[widgets_on_pages id=”udemy_advert_cpp_1″][widgets_on_pages id=”udemy_code_details”]

About this project

Skill level 1
Time to complete 90 minutes

New concepts

  • Building a simple reusable game engine in C++
  • Using textures with Sprites
  • Managing lengthy code with abstraction

Recommended preparation tutorials

  • Know where you want to start
  • Find out what is SFML.
  • C++game coding level 1 introduction
  • C++ Game variables tutorial
  • Manipulatingthe value of game variables
  • Condition checking in a game
  • Structuring and branching code
  • Loops in C++ game code
  • Organizing game code with functions
  • Introduction to OOP for C++ games

Assumed previous experience

  • Basic proficiency with Windows
  • SetupSFML and Visual Studiodevelopment environment
  • Building your first SFMLgameproject
  • SFML variables demo: Movingcircles
  • SFML conditions and branching demo: Bouncing shapes
  • Building a simple Pong clone
(Video) So you want to make a Game Engine!? (WATCH THIS before you start)

Creating the simple game engine project in Visual Studio

To get started we need to create a new project in Visual Studio, complete with all the required properties to work with SFML. If you haven’t completed theBuilding your first SFMLgameprojectyou will need to do that first in order for the next steps to work.

These next steps set up our new SFML C++ game engine project.

  1. Open Visual Studio and from the main menu choose File | New Project. In the left-hand menu click C++.Select the HelloSFML template and name your project Simple Game Engine.
  2. Now click OK.
  3. Right-click the HelloSFML.cpp file under the Source Files heading from the right-hand Solution Explorer window. Choose Rename and rename the file to Main. This is a more appropriate name as this will indeed be the source file containing the main function.
  4. Open Main.cpp by double-clicking it. Now delete all of its contents as we will be starting with an empty file.
  5. Copy & paste the SFML .dll files from the YOUR_DRIVE:\SFML\bin to YOUR_DRIVE:\Visual Studio Stuff\Projects\Simple Game Engine\Simple Game Engine. Obviously, if you configured your development environment slightly differently then your folder names will vary.

Now we can get coding. All the code is on the page and all the assets you need are made available from this page, but please take a look at the bonus download offer.

[sociallocker id=”14566″]

Thanks for the love! Here is the link to the simple-game-engine-c-bonus-download

Click to download the bonus!

[/sociallocker]

Also, note that all the bonus downloads for this and every future tutorial is available on an exclusive download area for my Patreon subscribers.

Building a simple game engine in C++ (2)

Planning the simple game engine

One of the problems that we had in the Pong game was how long and unwieldy the code was. If you consider that Pong is perhaps the simplest game it is possible to make then we need to think about improving the structure of our code. Object oriented programmingin C++ allows us to break our code up into logical and manageable chunks called classes.

We will make a big improvement to the manageability of the code in this project compared to the Pong game with the introduction of an Engine class. The Engine class will have three
private functions. They are input, update, and draw. This should sound very familiar if you have done the Pong project. Each of these functions will hold a part of the code that was previously all in the main function. Each of these functions will be in a code file of its own, Input.cpp, Update.cpp, and Draw.cpp respectively.

There will also be one public function in the Engine class, which can be called with an instance of Engine which will be declared in Main.cpp. This function is appropriately called start and will be responsible for calling input, update, and draw, once for each frame of the game:

In addition, because we have abstracted the game loop to the Engine class, we can also move virtually all of the variables from main and make them members of Engine. All we need to do to get our game engine revving is create an instance of Engine and call its start function from main. Here is what the super-simple main function will look like when we are done. Don’t code it just yet, though.

int main(){// Declare an instance of EngineEngine engine;// Start the engineengine.start();// Quit the gamereturn 0;}

If you want to go way beyond this tutorial, please take a look at these three related books.

[widgets_on_pages id=”bcgp_cfgp_gpp”]

(Video) Introduction to C++: Sparky Engine (How To Make a Game Engine)

Now we can build the classes that we discussed.

Coding the Bob class

Bob is a simple class that will represent the player’s controllable character. It can only move left and right but when you see the code you will see that it would be trivial to extend this functionality. More significant, however, is that the Bob class can be easily copied and modified to become just about any type of game object you like. Simply apply the appropriate texture in the constructor, behaviour in theupdate function then declare, update and draw them in exactly the same way that we will soon see. If you want dozens, hundreds, or more of your new game object then just declare an entire array of them.

Bob.h

First, let’s code the header file of the Bob class.

Right-click Header Files in the Solution Explorer and select Add | New Item…. In the Add New Item window, highlight (by left-clicking) Header File (.h) and then in the Name field, type Bob.h. Finally, click the Add button. We are now ready to code the header file for the Bob class.

#pragma once#include <SFML/Graphics.hpp>using namespace sf;class Bob{// All the private variables can only be accessed internallyprivate:// Where is BobVector2f m_Position;// Of course we will need a spriteSprite m_Sprite;// And a texture// Bob has been working out and he is now a bit more muscular than before// Furthermore, he fancies himself in lumberjack attireTexture m_Texture;// Which direction(s) is the player currently moving inbool m_LeftPressed;bool m_RightPressed;// Bob's speed in pixels per secondfloat m_Speed;// Public functionspublic:// We will set Bob up in the constructorBob();// Send a copy of the sprite to mainSprite getSprite();// Move Bob in a specific directionvoid moveLeft();void moveRight();// Stop Bob moving in a specific directionvoid stopLeft();void stopRight();// We will call this function once every framevoid update(float elapsedTime);};

In the previous code, we declare objects of type Texture and Sprite. You will see in the next code how we associate these with each other so that whenever we do anything with the Sprite it will be adorned by this rather handsome Bob character. Notice also the is a Vector2f called m_Position which can be manipulated and will be used to set Bob’s current position on the screen.

Right-click and select Save Image as… to download the previous image.

There are also two Boolean variables which will be set and unset in order to communicate with the update function which way Bob should be moving, if at all. There is also an int called m_Speed which will beassigned a value which determines how fast Bob will move.

The public section of the class has a getSprite function to return a copy of the Sprite object to the draw function where it is required in order to draw Bob to the screen. There are four setter functions moveLeft, moveRight, stopLeft, and stopRight. These functions will be called from the input function and are used to set the values of the two Booleans that control the movement.

The final function in the Bob.h file is the update function. You can see it takes a float variable. This function will be called each and every frame from the update function of the Engine class and will update Bob’s position by the right amount in the appropriate direction each frame.

Bob.cpp

Now we can code the definitions for all the functions we have just seen.

Right-click Source Files in the Solution Explorer and select Add | New Item…. In the Add New Item window, highlight (by left-clicking) C++ File (.cpp) and then in the Name field, type Bob.cpp. Finally, click the Add button. We are now ready to code the .cpp file for the Bob class.

#include "stdafx.h"#include "bob.h"Bob::Bob(){// How fast does Bob move?m_Speed = 400;// Associate a texture with the spritem_Texture.loadFromFile("bob.png");m_Sprite.setTexture(m_Texture);// Set the Bob's starting positionm_Position.x = 500;m_Position.y = 800;}// Make the private spite available to the draw() functionSprite Bob::getSprite(){return m_Sprite;}void Bob::moveLeft(){m_LeftPressed = true;}void Bob::moveRight(){m_RightPressed = true;}void Bob::stopLeft(){m_LeftPressed = false;}void Bob::stopRight(){m_RightPressed = false;}// Move Bob based on the input this frame,// the time elapsed, and the speedvoid Bob::update(float elapsedTime){if (m_RightPressed){m_Position.x += m_Speed * elapsedTime;}if (m_LeftPressed){m_Position.x -= m_Speed * elapsedTime;}// Now move the sprite to its new positionm_Sprite.setPosition(m_Position);}

In the constructor function, Bob, above we set m_Speed to 400 which means Bob would cross a 1920 pixel screen width in around 5 seconds. We load the bob.png image into the Texture object and we associate it with the Sprite object. We also set the starting horizontal and vertical positions for Bob by initializing m_Position.x and m_Position.y. It is worth noting that depending on the resolution of your monitor you might want to adjust these values.

The getSprite function as expected returns a copy of m_Sprite. The four movement related functions play with our two Booleans. The ...Pressed functions set the appropriate Boolean to true and the stop... functions set the same to false. We can now see how all these ties together in the update function.

The update function starts with two if statements. The first checking whether m_RightPressed is true and the second detecting whether m_LeftPressed is true. Inside each of the if blocks m_Speed multiplied by elapsedTime is added or subtracted from m_Position.x. The elapsedTime variable is calculated and passed in by the start function of the Engine class. We will code that next.

As a final step for this class add bob.png to the Simple Game Engine/Simple Game Engine folder.

Coding the Engine class

The Engine class is what controls everything else. Once it is started in the main function which runs when the app runs it will hold control right up until the player quits the game. Let’s code it now, it is quite straightforward.

(Video) Programming a first person shooter from scratch like it's 1995

Engine.h

Right-click Header Files in the Solution Explorer and select Add | New Item…. In the Add New Item window, highlight (by left-clicking) Header File (.h) and then in the Name field, type Engine.h. Finally, click the Add button. We are now ready to code the header file for the Engine class. Add the following code.

#pragma once#include <SFML/Graphics.hpp>#include "Bob.h";using namespace sf;class Engine{private:// A regular RenderWindowRenderWindow m_Window;// Declare a sprite and a Texture for the backgroundSprite m_BackgroundSprite;Texture m_BackgroundTexture;// An instance of BobBob m_Bob;// Private functions for internal use onlyvoid input();void update(float dtAsSeconds);void draw();public:// The Engine constructorEngine();// start will call all the private functionsvoid start();};

Let’s talk about the variables first. There is an SFML RenderWIndow which is what we use to display everything. There is a Sprite and a Texture which will be used to draw a pretty background image. We declare an instance of the Bob class that we just finished coding a moment ago. There is also thethree private functions, input, update, and draw. They are private because we don’t need or want to call them from outside of the Engine class.

Next, the code declares two public functions. The constructor called Engine will set the instance of the class up ready go and the start function is the function that will continuously call the input, update and draw functions, in that order, every frame.

Engine.cpp

In the Engine.cpp file, we will put the constructor (Engine) and the public start function. All the rest of the functions will go in their own .cpp file, with a name that makes it clear what function goes where. This will not be a problem for the compiler as long as we add the appropriate include directive (#include "Engine.h") at the top of all the files that contain function definitions from the Engine class.

Let’s get started by coding Engine and start in Engine.cpp. Right-click Source Files in the Solution Explorer and select Add | New Item…. In the Add New Item window, highlight (by left-clicking) C++ File (.cpp) and then in the Name field, type Engine.cpp. Finally, click the Add button. We are now ready to code the .cpp file for the Engine class.

#include "stdafx.h"#include "Engine.h"Engine::Engine(){// Get the screen resolution and create an SFML window and ViewVector2f resolution;resolution.x = VideoMode::getDesktopMode().width;resolution.y = VideoMode::getDesktopMode().height;m_Window.create(VideoMode(resolution.x, resolution.y),"Simple Game Engine",Style::Fullscreen);// Load the background into the texture// Be sure to scale this image to your screen sizem_BackgroundTexture.loadFromFile("background.jpg");// Associate the sprite with the texturem_BackgroundSprite.setTexture(m_BackgroundTexture);}void Engine::start(){// TimingClock clock;while (m_Window.isOpen()){// Restart the clock and save the elapsed time into dtTime dt = clock.restart();// Make a fraction from the delta timefloat dtAsSeconds = dt.asSeconds();input();update(dtAsSeconds);draw();}}

The constructor function gets the screen resolution and then opens a fullscreen window with m_Window.create. Finally, in the constructor, we load the image into the Texture and associate it with the Sprite.

You need to add an image for the background. Here is a great place to get lots of images with varying sizes.

http://www.spyderonlines.com/wallpapers/game-background-images.html

Use an image editor like GIMP or Photoshop to scale the background to the same resolution as your screen. Rename the image as background.jpg. Add the backgroung.jpg image tothe Simple Game Engine/Simple Game Engine folder.

The other function in the code above is the start function. This function contains just a continuous while loop that will only break when the window (m_Window) is closed. We will give the player the ability to do this in the input function soon.

The start function then calculates how long the previous frame took, stores the answer as a float called dtAsSeconds then calls input, update and draw. Notice that dtAsSeconds getpassed to update that will require the value because it will be calling the update function of the Bob instance.

I hope you agree that is extremely simple. It is arguably easier than have to handle the sprawl of code that we did in the Pong game.

Coding the three stages of the game loop

[widgets_on_pages id=”udemy_advert_cpp_2″][widgets_on_pages id=”udemy_code_details”]
The next three functions will be coded in their own individual files but don’t forget that they are part of the Engine class and were declared in the Engine.h file. At the top of each file, we will add the directive #include "Engine.h" so that Visual Studio knows what we are doing.

Handling player input

The first of these functions we will code is input.

Right-click Source Files in the Solution Explorer and select Add | New Item…. In the Add New Item window, highlight (by left-clicking) C++ File (.cpp) and then in the Name field, type Input.cpp. Finally, click the Add button. Here is the code for Input.cpp.

#include "stdafx.h"#include "Engine.h"void Engine::input(){// Handle the player quittingif (Keyboard::isKeyPressed(Keyboard::Escape)){m_Window.close();}// Handle the player movingif (Keyboard::isKeyPressed(Keyboard::A)){m_Bob.moveLeft();}else{m_Bob.stopLeft();}if (Keyboard::isKeyPressed(Keyboard::D)){m_Bob.moveRight();}else{m_Bob.stopRight();}}

In the input function, we use the SFML Keyboard::isKeyPressed constants to verify which keyboard keys are currently pressed. If the Escape key is pressed m_Window is closed. This has the effect of breaking out of the while loop in the start function. This causes execution to go back to the main function and the game will close.

If the A or D keys are pressed we call the appropriate move... function on our Bob instance. Notice that when the A or D keys are not pressed the two else clauses call the corresponding stop... functions. This is the final piece of the puzzle that enables the player to move Bob left and right.

(Video) Car Game in C++ for Beginners | Easy Console Games Coding Tutorial

Updating the game objects

Next, we come to the super-simple update function. Any new objects you create should have their own update functions called from here. You should also add collision detection to the end of this function.

Right-click Source Files in the Solution Explorer and select Add | New Item…. In the Add New Item window, highlight (by left-clicking) C++ File (.cpp) and then in the Name field, type Update.cpp. Finally, click the Add button. Here is the code for Update.cpp.

#include "stdafx.h"#include "Engine.h"using namespace sf;void Engine::update(float dtAsSeconds){m_Bob.update(dtAsSeconds);}

As we only have one game object we call m_Bob.update and pass in dtAsSeconds and then we are finished with this function.

Drawing the scene

This is the final function of the Engine class.

Right-click Source Files in the Solution Explorer and select Add | New Item…. In the Add New Item window, highlight (by left-clicking) C++ File (.cpp) and then in the Name field, type Draw.cpp. Finally, click the Add button. Here is the code for Draw.cpp.

#include "stdafx.h"#include "Engine.h"void Engine::draw(){// Rub out the last framem_Window.clear(Color::White);// Draw the backgroundm_Window.draw(m_BackgroundSprite);m_Window.draw(m_Bob.getSprite());// Show everything we have just drawnm_Window.display();}

In the draw function, there is nothing that we didn’t see in the Pong game. First, we clear the screen with the clear function. Next, we draw the background followed by Bob. The things to note here are that we must draw the background first so Bob is drawn on top and that when we draw Bob we call the getSprite function which gets a copy of the Sprite in the Bob class.

Getting the engine started with Main

This is the shortest main function out of all the C++ tutorials on this site.

Add the code we have already glimpsed at to Main.cpp. Here it is again in its entirety.

#include "stdafx.h"#include "Engine.h"int main(){// Declare an instance of EngineEngine engine;// Start the engineengine.start();// Quit in the usual way when the engine is stoppedreturn 0;}

First, we declare an instance of Engine, call the start function and execution will move to the Engine class until the player quits by pressing the Escape key.

You can now run the game and move Bob left and right with the A and Dkeyboard keys.

Use the A and Dkeys to move

Conclusion, flaws & what next?

When you added the background and the player we had to adjust the code to suit your specific resolution. This is obviously not suitable for a game you want to release on Steam. It is quite easy to fix this flaw using the SFML View class. I didn’t add this feature because at some point I had to stop adding features. The View class uses OpenGL to make independent drawing layers and can be used to make some really cool effects like split-screen gameplay, mini maps, and levels that can rotate and zoom. I will publish a whole working game that uses these features soon.

Another obvious flaw that you probably spotted was that the game engine doesn’t handle for different game states like paused, home screen and playing. You can quickly cater for this by creating some Booleans to represent each state. Perhaps isPlaying, isPaused etc. This isn’t the best way of doing it but as I said before I had to draw the line at the features to include in what should be a simple tutorial. We will see a neater and more efficient way to handle states in a forthcoming full-game project, most likely a platformer.

In addition, any game you are going to release to the world will have more features like sound, music, artificial intelligence, saving of high scores and more besides. Most of these features can be bolted onto this engine. It is true, unfortunately, that eventually you will end up with code sprawl again but the purpose of the tutorial is meant to be instructional as well as practical and when we dive into something more complicated this engine should serve as good preparation and starting point.

I hope you had some fun with this simple C++ game engine. Please ask questions and leave comments if you would like to.

(Video) Building a Physics Engine with C++ and Simulating Machines

FAQs

Building a simple game engine in C++? ›

If you are dead set on making a game engine, you have to fully commit to every aspect. C++ is a great first thing to jump right into. It runs on nearly all platforms and is used with almost everything you will come across.

Can you make your own game engine with C++? ›

If you are dead set on making a game engine, you have to fully commit to every aspect. C++ is a great first thing to jump right into. It runs on nearly all platforms and is used with almost everything you will come across.

What is the easiest game to make in C++? ›

Flappy bird – This has lately become the like the “Hello, World” for game creation. It is easy to create and the rules are pretty simple. There are millions of these games and there were millions before flappy bird even existed.

Is C++ used in game engines? ›

C++ plays an important role in today's game development ecosystem. C++ is used in the source code of many major game engines, such as Unreal and Unity, allowing developers to build more high-performant games. Let's see why C++ is a better programming language for game development.

What is the best game engine to use in C++? ›

Best C++ Game Engines to use in 2023
  • Features and Benefits of Unity Game Engine.
  • Features and Benefits of Unreal Engine.
  • Features and Benefits of Godot.
  • Features and Benefits of Phaser are.
  • Features and Benefits of Game Maker Studio 2.
  • Features and Benefits of Adventure Game Studio.
  • Features and Benefits of CryEngine.

Is only C++ enough for game development? ›

As such, different codes present a different syntax and will be more efficient to perform certain tasks. C++ is the most widely used programming language in triple A video game development. However, many programming languages overlap and are compatible with each other, each contributing to the overall game experience.

Is Java or C++ better for making games? ›

In some cases, the decision between C++ and Java is clear. Native Android applications should typically use Java unless the app is a game. Most game developers should opt for C++ or another language for the smoothest possible real-time animation; Java's memory management often causes lag during gameplay.

Is C++ too hard for beginners? ›

Yes, C++ is harder to learn and work with than Python. The biggest difference is that C++ has a more complex syntax to work with and involves more memory management than Python, which is both simple to learn and use. Python is considered a better beginner programming language.

Is Python or C++ better for games? ›

Python runs more slowly than other programming languages like C++, and it isn't a conventional video game scripting language like C#. However, for newcomers, Python is one of the best starter programming languages—and game engines like Godot are basing their native scripts on Python to make it easier to program.

Why are most games coded in C++? ›

C++ produces native code that runs the quickest of all the languages programmers use. This language performs well when compared to others in terms of graphics. High frame rates and responsiveness are essential when creating console games, and C++ is crucial for it.

Should I make a game in C# or C++? ›

Both C# and C++ can be used to create games. However, C++ has better control hardware on the PC or server. Therefore, it is usually a more suitable language for game development. However, both languages are for game development, especially knowing that you won't be creating games from scratch (usually).

Should I make a game in Python or C++? ›

Python runs more slowly than other programming languages like C++, and it isn't a conventional video game scripting language like C#. However, for newcomers, Python is one of the best starter programming languages—and game engines like Godot are basing their native scripts on Python to make it easier to program.

Can I create my own game engine? ›

You can create a game engine to simplify the programming process for all of the games you make. If you're a developer looking to create your own game engine from scratch, check out this tutorial for coding your own a simple game engine!

Can I use C++ in Godot? ›

yes, you can use C++ with godot, but no you can't use it exactly the same as gdscript.

Videos

1. Tools to make a Game Engine in C++
(pikuma)
2. I Made a Graphics Engine
(Zyger)
3. If you want to learn how to make games in C++ watch this (All the resources you need to get started)
(Low Level Game Dev)
4. I Made a Game Engine (C++)
(Low Level Game Dev)
5. How to make a GAME ENGINE
(Guilherme Teres)
6. I Made My Own Game Engine
(n8dev)
Top Articles
Latest Posts
Article information

Author: Annamae Dooley

Last Updated: 15/09/2023

Views: 6155

Rating: 4.4 / 5 (65 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Annamae Dooley

Birthday: 2001-07-26

Address: 9687 Tambra Meadow, Bradleyhaven, TN 53219

Phone: +9316045904039

Job: Future Coordinator

Hobby: Archery, Couponing, Poi, Kite flying, Knitting, Rappelling, Baseball

Introduction: My name is Annamae Dooley, I am a witty, quaint, lovely, clever, rich, sparkling, powerful person who loves writing and wants to share my knowledge and understanding with you.