The Scene Class

Learn more about the structure of the Nero Scene Class

The Scene Class

The class nero::Scene is the main component of the Nero Game Engine. You create a new Game Scene by creating a new class inheriting nero::Scene, by doing so you get access to many features that will make building a new game easy. The Scene Class represents the logic of your game, its only purpose is to manage the lifetime of your Game Objects and the flow of your Game.

Take alone the Scene Class will seem useless, that’s because it has been designed to run inside a nero::Engine. A nero::Engine can Instantiate, Run, and Destroy any Scene Class. There are currently three (3) nero::Engines

  • The nero::DevEngine which is simply our Engine Editor
  • The nero::SceneRenderer which is used when you click on the button Render located on the Editor Toolbar
  • The nero::RenderEngine which is used to render your Final Game

The method bool isRenderEngine() lets you know if your Scene is currently run inside the Engine Editor or the Render Engine. The nero::SceneRenderer is a lightweight version of the nero::RenderEngine, so it is considered also a Render Engine.

Below you can have a look at the nero::Scene header file

 ////////////////////////////////////////////////////////////
// Nero Game Engine
// Copyright (c) 2016-2019 SANOU A. K. Landry
/////////////////////////////////////////////////////////////
#ifndef SCENE_H
#define SCENE_H
///////////////////////////HEADERS//////////////////////////
//NERO
#include <Nero/scene/SceneUtil.h>
#include <Nero/scene/SoundManager.h>
#include <Nero/scene/ScriptManager.h>
#include <Nero/scene/ShapeRenderer.h>
#include <Nero/scene/ObjectManager.h>
#include <Nero/model/Collision.h>
#include <Nero/object/Object.h>
#include <Nero/object/UIObject.h>
#include <Nero/model/FrontScreen.h>
//SFGUI
#include <SFGUI/Canvas.hpp>
//SFML
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/Sprite.hpp>
//LUA
#include <lua/lua.hpp>
////////////////////////////////////////////////////////////
namespace nero
{
    class Scene : public b2ContactListener
    {
        public:
            typedef std::shared_ptr Ptr;

            struct Context
            {
                Context(sfg::Canvas::Ptr renderCanvas, sf::View& frontView, Camera::Ptr camera, ResourceManager::Ptr resourceManager, bool renderEngine);

                sfg::Canvas::Ptr        renderCanvas;
                sf::View&               frontView;
                Camera::Ptr             camera;
                ResourceManager::Ptr    resourceManager;
                bool                    renderEngine;
            };

                                        Scene(Context context);
            virtual                    ~Scene();

            virtual void                handleEvent(const sf::Event& event);
            virtual void                update(const sf::Time& timeStep);
            virtual void                render();
            virtual void                renderShape();
            virtual void                renderFrontScreen();

        protected:
            virtual void                init();
            virtual void                checkSceneObject();
            //Collision
            virtual void                handleCollisionContactBegin(Collision collision);
            virtual void                handleCollisionContactEnd(Collision collision);
            virtual void                handleCollisionPreSolveContact(Collision collision);
            virtual void                handleCollisionPostSolveContact(Collision collision);
            //Input
            virtual void                handleKeyboardInput(const sf::Keyboard::Key& key, const bool& isPressed);
            virtual void                handleMouseButtonInput(const sf::Event::MouseButtonEvent& mouse, const bool& isPressed);
            virtual void                handleMouseMoveInput(const sf::Event::MouseMoveEvent& mouse);
            virtual void                handleMouseWheelInput(const sf::Event::MouseWheelScrollEvent& mouse);
            //Scene
            bool                        isScenePause();
            void                        pauseScene();
            void                        resumeScene();
            void                        resetScene();
            void                        quitScene();
            void                        hideWorld();
            void                        showWorld();
            void                        hideScreen(const std::string& name);
            void                        showScreen(const std::string& name);
            void                        pushScreen(const std::string& name);
            void                        popScreen();
            bool                        isRenderEngine();
            //
            const std::string&          getSceneName() const;
            const Context&              getContext() const;
            Object::Ptr                 getWorld();
            b2World*                    getPhysicWorld();
            void                        setCanvasColor(const sf::Color& color);
            const sf::Color&            getCanvasColor() const;
            const sf::Color&            getScreenCanvasColor(const std::string& name) const;
            ObjectManager::Ptr          getObjectManager();
            SoundManager::Ptr           getSoundManager();
            ScriptManager::Ptr          getScriptManager();
            SceneSetting&               getSceneSetting();
            CameraSetting&              getCameraSetting();
            float                       getFrameRate();
            float                       getFrameTime();
            //Camera Target
            void                        setCameraTarget(Object::Ptr target);
            void                        enableFollowTaget(bool flag);
            void                        updateTargetOffset(const float left, const float right, const float up, const float down);
            //Log
            void                                                    log(const std::string& content, int level = nero::Info);
            void                                                    logIf(const std::string& content, bool condition, int level = nero::Info);
            std::function<void(const std::string&, int)>            getLog();
            std::function<void(const std::string&, bool, int)>      getLogIf();
            //resolution
            virtual sf::Vector2f                getSceneResolution();

            //
            void                        disableLayer(const std::string& name);
            void                        enableLayer(const std::string& name);

        private:
            void                        BeginContact(b2Contact* contact);
            void                        EndContact(b2Contact* contact);
            void                        PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
            void                        PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);

            void                        followTarget();

            void                        enableScreen(const std::string& name, bool flag);

        private:
            //Friend
            friend class                DestructionListener;
            friend class                BoundaryListener;
            friend class                ContactListener;
            friend class                AdvancedScene;
            friend class                SceneManager;
            friend class                RenderEngine;
            friend class                SceneRenderer;
            //Main Attribute
            std::string                 m_SceneName;
            Context                     m_Context;
            b2World*                    m_PhysicWorld;
            Object::Ptr                 m_World;
            std::vector    m_ScreenStack;
            std::vector    m_ScreenTable;
            //Manager & Setting
            ShapeRenderer               m_ShapeRenderer;
            ObjectManager::Ptr          m_ObjectManager;
            SoundManager::Ptr           m_SoundManager;
            ScriptManager::Ptr          m_ScriptManager;
            SceneSetting                m_SceneSetting;
            CameraSetting               m_CameraSetting;
            //Utility
            CameraTarget                m_CameraTarget;
            sf::Color                   m_CanvasColor;
            sf::Color                   m_SceenCanvasColor;
            bool                        m_HideWorld;
            //Other
            int32                       m_PointCount;
            sf::Text                    m_Text;
            sf::String                  m_PauseMessage;
            ContactPoint                m_Points[k_maxContactPoints];
            //FrameRate
            float                       m_FrameRate;
            float                       m_FrameTime;
            //Callback
            std::function<void()>                           m_QuitEngine;
            std::function<void()>                           m_ResetScene;
            std::function<void(std::string, int)>           m_UpdateLog;
            std::function<void(std::string, bool, int)>     m_UpdateLogIf;
    };
}
#endif // SCENE_H

Game World - Physic World - Game Screen Table

The three (3) main components of your Game Scene are the Game World, the Physics World, and the Game Screen Table

  • The Game World is your Scene Graph or simply put, a tree-like data structure that contains all the Game Objects of your Scene. The Game World is organized as presented below. At the top you have the Root Object, then an unlimited number of Layer Objects, and below each Layer, you have all your Game Objects. You can retrieve the Root Object with the method Object::Ptr getWorld().
  • The Physic World is the place where all the physics computation happens, this world is managed entirely by Box2D. You can retrieve the Physic World with the method b2World* getPhysicWorld().
  • The Game Screen Table contains all the Game Screens created in the Engine Editor.

The Context Object

The only argument of the nero::Scene constructor is the nero::Scene::Context object. You do not create a Context object by yourself. The Context object is created by a nero::Engine. The nero::Engines use the Context object to share some resources with your Scene Class. As you can see below the resources shared are the followings :

  • The Render Canvas : which is the drawing surface of your game window.
  • the Front View : allows you do draw anything on top the Game World, the Engine uses this view to draw your Game Screens.
  • The Camera : the Game World main Camera View.
  • The Resource Manager : store and provide access to all you game assets.
  • The Engine Type : a boolean indicating if the Scene is running inside the Engine Editor or a Render Engine.
class MyScene: public nero::Scene
{
    public:
      	MyScene(nero::Scene::Context context);
};
struct Context
{
    Context(sfg::Canvas::Ptr renderCanvas, sf::View& frontView, Camera::Ptr camera, ResourceManager::Ptr resourceManager, bool renderEngine);

    sfg::Canvas::Ptr        renderCanvas;
    sf::View&               frontView;
    Camera::Ptr             camera;
    ResourceManager::Ptr    resourceManager;
    bool                    renderEngine;
};

Overridable Methods

The Scene Class provides a lot of methods that are mean to be overridden. Build your Game Logic will mostly consist to override the right method and implement the desired behavior. Those methods can be classified into four (4) groups :

  • Game Loop : Most of the time you will not have to override those methods. There are the main methods of your game. The three methods handleEvent( event ), update( time ) and render() constitute your Game Loop. The Engine uses three render methods just for a better architecture of the code. the method render() draws your Game World, the method renderShape() draws some Physics Information and the method renderFrontScreen() draw yours Game Screens.
  • Initialization : The three (3) methods init(), checkSceneObject() and getSceneResolution() are used during the initialization phase of your game.
  • Collision : The four methods handleCollision [ContactBegin, ContactEnd, PreSolveContact, PostSolveConstact] are used to react to collisions.
  • Input : The four methods handleKeyboardInput, and handleMouse [ButtonInput, MoveInput, WheelInput) let you react to any keyboard and mouse inputs.
//Game Loop
virtual void handleEvent(const sf::Event& event);
virtual void update(const sf::Time& timeStep);
virtual void render();
virtual void renderShape();
virtual void renderFrontScreen();
//Initialization
virtual void init();
virtual void checkSceneObject();
virtual sf::Vector2f getSceneResolution();
//Collision
virtual void handleCollisionContactBegin(Collision collision);
virtual void handleCollisionContactEnd(Collision collision);
virtual void handleCollisionPreSolveContact(Collision collision);
virtual void handleCollisionPostSolveContact(Collision collision);
//Input
virtual void handleKeyboardInput(const sf::Keyboard::Key& key, const bool& isPressed);
virtual void handleMouseButtonInput(const sf::Event::MouseButtonEvent& mouse, const bool& isPressed);
virtual void handleMouseMoveInput(const sf::Event::MouseMoveEvent& mouse);
virtual void handleMouseWheelInput(const sf::Event::MouseWheelScrollEvent& mouse);

Action Methods

The second category of methods provided by the Scene Class is the Action methods. Those methods let you ask the Scene Class to perform some actions or tasks like pausing the game or displaying a certain game screen. Those methods can be classified in seven (7) groups :

    • Scene Llife Cycle
    • Game World
    • Game Screen
    • Layer Object
    • Camera Target
    • Canvas
    • logging
//Scene Life Cycle
void                        pauseScene();
void                        resumeScene();
void                        resetScene();
void                        quitScene();
bool                        isScenePause();
//Game World
void                        hideWorld();
void                        showWorld();
//Game Screen
void                        hideScreen(const std::string& name);
void                        showScreen(const std::string& name);
void                        pushScreen(const std::string& name);
void                        popScreen();
//Layer Object
void                        disableLayer(const std::string& name);
void                        enableLayer(const std::string& name);
//Camera Target
void                        setCameraTarget(Object::Ptr target);
void                        enableFollowTaget(bool flag);
void                        updateTargetOffset(const float left, const float right, const float up, const float down);
//Canvas
void setCanvasColor(const sf::Color& color);
//Logging void log(const std::string& content, int level = nero::Info); void logIf(const std::string& content, bool condition, int level = nero::Info);

Getter Methods

The third and last category of methods provided by the Scene Class is the Getter Methods. These methods let you access certain components of your Scene Class.

const std::string&          getSceneName() const;
const Context&              getContext() const;
Object::Ptr                 getWorld();
b2World*                    getPhysicWorld();
const sf::Color&            getCanvasColor() const;
const sf::Color&            getScreenCanvasColor(const std::string& name) const;
ObjectManager::Ptr          getObjectManager();
SoundManager::Ptr           getSoundManager();
ScriptManager::Ptr          getScriptManager();
SceneSetting&               getSceneSetting();
CameraSetting&              getCameraSetting();
float                       getFrameRate();
float                       getFrameTime();
bool                        isRenderEngine();
std::function<void(const std::string&, int)>            getLog();
std::function<void(const std::string&, bool, int)>      getLogIf();

You have successfully subscribed to the newsletter

There was an error while trying to send your request. Please try again.

Nero Games will use the information you provide on this form to be in touch with you and to provide updates and marketing.