Engine and Scene
Learn how to create a simple Engine and Scene Class
Code Repository
- The code for this tutorial can be found on Github : Learn SFML – Simple Engine and Scene
Designing our Engine and Scene Classes
This SFML tutorial series will be divided into topics or lessons. For each of those lessons, we’ll have to create a new project and set up the basic code that provides the window and the game loop, only after that, we’ll be able to start the lesson. What if we could separate the Lesson code from the Basic code so that, for each new Lesson we’ll only have to write the Lesson code.
The pseudo-code below shows how this would look. For each new lesson, we’ll just have to create a new class “MyNewLesson” that will inherit a base class called “BaseLesson”. This way we only have to write the code we need in MyNewLesson and the BaseLesson class will take care of the rest. Then we provide our lesson “MyNewLesson” to an Engine that will create a window and render the lesson for us.
//create a new lesson class MyNewLesson : public BaseLesson { //write the new lesson (only the code we need) }; int main() { //Let the Engine run our new lesson Engine engine; engine.setLesson(MyNewLesson()); engine.start(); }
The Real Code
For our implementation, the BaseLesson class will be called Scene (short for Game Scene) and the Engine class will be called Engine (who could have guessed that !?)
The code below (main.cpp) shows the result we want to achieve.
- The Engine Class lets us create a new Game Window by specifying the window width, the window height, and the frame rate we want to use (60 FPS for example)
- The Scene Class is our actual game (or lesson here) and can be played or run by the Engine.
- To have a clear separation between our game/lesson code and our Engine Base code, we encapsulate all the Engine Base code inside a namespace called “ng” (short for nero games). In the code below you can see ng::Engine, this means that the class “Engine” is part of the namespace “ng“, same for ng::Scene.
//////////////////////////////////////////////////////////// // Nero Game Engine - SFML Tutorials //////////////////////////////////////////////////////////// ///////////////////////////HEADERS////////////////////////// #include "Engine.h" //////////////////////////////////////////////////////////// int main() { //create new Engine instance with(width, height, frame-rate (60FPS or 120FPS)) ng::Engine engine(1080, 720, 60); //provide our Scene to the Engine using a Smart Unique Pointer (Ptr) engine.setScene(ng::Scene::Ptr(new ng::Scene())); //run the Engine (the game) engine.run(); return 0; }
Scene Class
The image below shows the lifecycle of our Scene Class. After the Scene is created, it gets initialized, then it enters the Game Loop. After leaving the Game Loop it gets destroyed.

Base on the image above we’ll need at least five methods in our Scene class
- Init() : used to build the game initial state (before entering the game loop)
- HandleEvent(const sf::Event& event) : used to capture the user inputs with SFML Events (happens at each frame during the game loop)
- Update(const sf::Time& timeStep) : used to update the game objects properties like positions, animations, etc. (happens at each frame during the game loop)
- Render() : used to draw all the game objects (happens during the game loop)
- Destroy : used to destroy all our game data (after leaving the game loop)
//////////////////////////////////////////////////////////// // Nero Game Engine - SFML Tutorials //////////////////////////////////////////////////////////// #ifndef SCENE_H #define SCENE_H ///////////////////////////HEADERS////////////////////////// //SFML #include <SFML/Graphics/RenderWindow.hpp> //CPP #include <memory> //////////////////////////////////////////////////////////// namespace ng { class Scene { public: typedef std::unique_ptr<Scene> Ptr; public: Scene(); virtual ~Scene(); public: virtual void init(); virtual void handleEvent(const sf::Event& event); virtual void update(const sf::Time& timeStep); virtual void clear(); virtual void render(); virtual void destroy(); public: //getter std::string getSceneName() const; sf::Vector2f getSceneResolution() const; sf::RenderWindow& getRenderWindow() const; //setter void setSceneName(const std::string& name); private: friend class Engine; std::string m_SceneName; sf::Vector2f m_Resolution; sf::RenderWindow* m_RenderWindow; }; } #endif // SCENE_H
Engine Class
The image below shows the lifecycle of our Engine class. After the Engine is created, we provide it our Scene, then we let it run which will initialize the Scene, run the Game Loop and destroy the Scene.

The code below shows the content of the ng::Engine run() method. At the very beginning of the method, the method init() is called, this is when our Scene is initialized. Then we enter the Game Loop where the game will Handle Events, Update and Render. Finally, when we exit the game loop the method destroy() is called, this is when our Scene gets destroyed.
void Engine::run() { //Initialize game init(); //Variable to store the time that passes sf::Time timePassed = sf::Time::Zero; //Create a clock, the clock starts automatically sf::Clock clock; //Entering the game loop while(m_RenderWindow.isOpen()) { //Retrieve the clock time and reset the clock at the same time sf::Time clockTime = clock.restart(); //Accumulate the time passing in our variable (this happens at each cycle of the while loop) timePassed += clockTime; //When the time passing is over our Fixed Time only Capture Inputs and Update the Game while(timePassed > m_FrameRate) { //Remove (0.0166) seconds from the passing time //Only the overflow will remain for the next frame timePassed -= m_FrameRate; //capture the user inputs using SFML Events handleEvent(); //update the game at the fixed time frame of (0.0166 second) update(m_FrameRate); } //Render the game //We do not render the game at 60 FPS, only the update happens at 60 FPS render(); } destroy(); }
Example : Create a Custom Scene
Now that we have our Engine and Scene classes, let’s try them. The code below shows how to create a custom Scene named Circle Scene. This scene is pretty simple, it displays a green circle that follows the movement of your mouse.

Here is the full code of the Circle Scene Class.
//////////////////////////////////////////////////////////// // Nero Game Engine - SFML Tutorials //////////////////////////////////////////////////////////// #ifndef CIRCLESCENE_H_INCLUDED #define CIRCLESCENE_H_INCLUDED ///////////////////////////HEADERS////////////////////////// //Nero Games #include "Scene.h" //SFML #include "SFML/Graphics.hpp" //////////////////////////////////////////////////////////// class CircleScene : public ng::Scene { private: sf::CircleShape mCircle; sf::Vector2f mCirclePosition; public: typedef std::unique_ptr<CircleScene> Ptr; CircleScene() { setSceneName("Circle Scene v0.1"); } public: void init() { mCircle.setRadius(100.f); mCircle.setOrigin(100.f, 100.f); mCircle.setFillColor(sf::Color::Green); mCirclePosition.x = getSceneResolution().x/2.f; mCirclePosition.y = getSceneResolution().y/2.f; mCircle.setPosition(mCirclePosition); } void handleEvent(const sf::Event& event) { //default event handle (close the window) ng::Scene::handleEvent(event); //capture the mouse position if (event.type == sf::Event::MouseMoved) { mCirclePosition.x = event.mouseMove.x; mCirclePosition.y = event.mouseMove.y; } } void update(const sf::Time& timeStep) { mCircle.setPosition(mCirclePosition); } void render() { getRenderWindow().draw(mCircle); } }; #endif // CIRCLESCENE_H_INCLUDED
Here is the code inside the main.cpp file
//////////////////////////////////////////////////////////// // Nero Game Engine - SFML Tutorials //////////////////////////////////////////////////////////// ///////////////////////////HEADERS////////////////////////// #include "Engine.h" #include "CircleScene.h" //////////////////////////////////////////////////////////// int main() { //create new Engine instance ng::Engine engine(1080, 720, 60); //provide Scene to Engine engine.setScene(CircleScene::Ptr(new CircleScene())); //run the Engine engine.run(); return 0; }