Hello to the “Working with scenes part 2” tutorial, please make sure that you read all the previous tutorials before starting reading this one. In this article I’m going to continue with the scenes that we developed in the last tutorial in order to introduce some new concepts that are available in Isaac.
Transient Data
Transient data are variables that are available for all the scenes. A scene can ask for a transient data or can update a transient data for another scene. This variables are hold in an any structure that is available in boost. Let’s say that from the SceneTwo we want to control the motion speed for the rectangle that is present in the SceneOne. In order to do this we need to declare a transient data in the StaticAspect class:
void StaticAspect::mp_DefineTransientData() const { double speed = 1; mp_AddTransientData(speed, "Speed"); }
Now we have a variable that is transient (it is available for all the defined scenes), we are going to use this variable in the SceneOne for the rectangle motion. So, let’s see how we can do this. Go to the source code of the SceneOne and get the transient data:
void SceneOne::mp_UpdateScene(std::shared_ptr<sf::RenderWindow> av_xMainWindow, std::shared_ptr<const isaac::CTransientDataCollection>& av_xTransientData, sf::Event av_eventSFMLEvent, bool& av_bReturnedBool_WindowClosed) { double speed = av_xTransientData->mf_xGetTransientData<double>("Speed"); mv_pRect->move(speed, 0); }
Now we need to update this value from the second scene, in order to do this:
void SceneTwo::mp_InitScene(std::shared_ptr<sf::RenderWindow> av_xMainWindow, std::shared_ptr<const isaac::CTransientDataCollection>& av_xTransientData) { circle = new sf::CircleShape(30); circle->setPosition(300, 300); double speed = av_xTransientData->mf_xGetTransientData<double>("Speed"); ++speed; av_xTransientData->mp_UpdateTransientData<double>("Speed", speed); std::cout << "Scene Two - Init" << std::endl; }
Now every time the second scene it will activate, the rectangle speed it will increase, making the rectangle to move faster and faster with every instance of “SceneOne”. This is how you can work with transient data in Isaac. Is important to know that a transient data can be represented by any kind of variable, in this example we used a double, but you can use any kind of data types that you want.
Father Scenes
This is a new concept that you can use in your projects. A scene can be a father scene for other scenes. The father scene will be visible when the scenes that are calling him father are visible. In other words if the scene that is displayed has a father scene, that scene it will be also visible. A father scene can also have a father scene and that father scene can also have a father scene 🙂 (Inception like).
So, let’s try to make an example, first of all create a new scene and name it “SceneThree”, the header file:
#pragma once #include <IStaticScene.h> class SceneThree : public isaac::IStaticScene { private: sf::RectangleShape* mv_Shape; public: SceneThree(std::string ac_szSceneName); void mp_InitScene(std::shared_ptr<sf::RenderWindow> av_xMainWindow, std::shared_ptr<const isaac::CTransientDataCollection>& av_xTransientData); void mp_InitTriggers(std::shared_ptr<isaac::CTriggerCollection>& ac_xGlobalTriggersColl); void mp_UpdateScene(std::shared_ptr<sf::RenderWindow> av_pMainWindow, std::shared_ptr<const isaac::CTransientDataCollection>& av_xTransientData, sf::Event av_eventSFMLEvent, bool& av_bReturnedBool_WindowClosed); void mp_DrawScene(std::shared_ptr<sf::RenderWindow> av_pMainWindow) const; void mp_Release(std::shared_ptr<const isaac::CTransientDataCollection>& av_xTransientData, std::string ac_szTriggerName); ~SceneThree(); };
Nothing special with this one, just a private variable that is a RectangleShape. Let’s see the source code:
#include "SceneThree.h" #include <ITrigger.h> #include <iostream> SceneThree::SceneThree(std::string ac_szSceneName) : isaac::IStaticScene(ac_szSceneName) { ; } void SceneThree::mp_InitScene(std::shared_ptr<sf::RenderWindow> av_xMainWindow, std::shared_ptr<const isaac::CTransientDataCollection>& av_xTransientData) { mv_Shape = new sf::RectangleShape(sf::Vector2f(60, 30)); mv_Shape->setPosition(0, 400); std::cout << "Initi father scene" << std::endl; } void SceneThree::mp_InitTriggers(std::shared_ptr<isaac::CTriggerCollection>& ac_xGlobalTriggersColl) { ; } void SceneThree::mp_UpdateScene(std::shared_ptr<sf::RenderWindow> av_xMainWindow, std::shared_ptr<const isaac::CTransientDataCollection>& av_xTransientData, sf::Event av_eventSFMLEvent, bool& av_bReturnedBool_WindowClosed) { } void SceneThree::mp_DrawScene(std::shared_ptr<sf::RenderWindow> av_xMainWindow) const { av_xMainWindow->draw(*mv_Shape); } void SceneThree::mp_Release(std::shared_ptr<const isaac::CTransientDataCollection>& av_xTransientData, std::string ac_szTriggerName) { delete mv_Shape; } SceneThree::~SceneThree() { }
Nothing special with this one either, just init the rectangle and draw it somewhere on the screen. Now, we are going to set this scene as father scene for the other two scenes that we have defined. In order to do this, go to the StaticAspect class and modify :
void StaticAspect::mp_DefineScenes() const { const auto& firstScene = std::make_shared<SceneOne>("SceneOne"); const auto& secondScene = std::make_shared<SceneTwo>("SceneTwo"); const auto& fatherScene = std::make_shared<SceneThree>("FatherScene"); firstScene->mp_SetFatherScene(fatherScene); secondScene->mp_SetFatherScene(fatherScene); mp_AddScene(firstScene); mp_AddScene(secondScene); mp_AddScene(fatherScene); }
By doing this the rectangle that we drew on the third scene it will be available when SceneOne it will be active and also when SceneTwo it will be active. This is how the father states are working in Isaac. Hope you like it, see you on the next tutorial. Bye 🙂