Singletons in Cocos2d-x?

I’m used to creating games using Singletons for the menus, gameplaystates, and pause menus, etc, with some states going over overs (pause being over the gameplay).

I’m a little confused on how they work here.

I’m always used to having…

CGame* CGame::GetInstance()
{
        static CGame instance;

        return &instance;
}


void CGame::PushState(IGameState *pNewState)
{
        if(pNewState)
        {
                pNewState->Enter();
                m_vStackedStates.push_back(pNewState);
        }
}

IGameState* CGame::PopState()
{
        IGameState* pTempState = m_vStackedStates[m_vStackedStates.size() - 1];

        pTemptState->Exit();
        m_vStackedStates.pop_back();

        return pTempState;
}

And such like that even with a ChangeState function.

How does it work here? Do I need to be using the pDirector->runWithScene(pScene)?

Any help would be appreciated.

I don’t catch it. Could you explain it more detail?

Well, the ways I’ve programmed games before I’ve used singletons for the states of the games. I’m not sure how to do this or how I’m supposed to use it via Cocos2d-x.

The way it would do is show the MainMenuState at first. When I click “Start Game”, it would then pop the MainMenuState and push the GameState on to have the game be played. If I wanted to pause, it would push the state of PauseMenuState (and not pop the GameState) off, thereby allowing both to be rendered, but only the PauseMenuState to be updated. When I would quit via the PauseMenuState, it would pop both the PauseMenuState and the GameState and push on the MainMenuState to return to the main menu.

I’m basically wondering how it is supposed to be done via Cocos2d-x. I’m not exactly sure how to change between the “states”, which is why I asked about the pDirector->runWithScene() function. Is that supposed to be like what is rendered/updated?

If you want to render a sprite(a object that contain the picture data), you should add it to a scene, and remove it from the scene or set display to false when you don’t want to render it.

Hmm… I may not be explaining this properly.

I’m referring to completely different states of things happening at different times.

For instance, the MainMenuState has different options to choose from (Play Game, Settings, Credits) and a main logo. You click the Settings or Credits and you’ll get what it shown. This has its own set of input, updating and whatnot. Just different things shown (and for the settings, things that can be changed - sounds and music, etc). But when you click the Play Game option, all that is the MainMenuState goes away

In return, a new state is shown, the GameState. What this is all the things that are for the actual game. This has a completely different set of input, updating, which pertain to the GameState. When I quit out of the GameState (via an input button in the GameState), the old MainMenuState comes back and everything that it has/uses comes back.

This is more than just having different things rendered. It’s like the scenes that I’m reading, but I’m not entirely sure if these are the “scenes”. It also may be layers. But that’s why I’m asking what would I be using to get this stuff to happen.

I’m sorry if this still doesn’t explain it properly.

Is the pDirector->runWithScene() what I’m thinking it does? It only uses the scene I see? So I could have 2 different scenes happening (for instance, 2 tutorial scenes, one being the one shown and the other with the guy being on the left and the enemies coming from the top)?

Wait, I’m pretty sure I found what I needed in CCDirector.h…

    /**Enters the Director's main loop with the given Scene. 
     * Call it to run only your FIRST scene.
     * Don't call it if there is already a running scene.
     */
    void runWithScene(CCScene *pScene);

    /**Suspends the execution of the running scene, pushing it on the stack of suspended scenes.
     * The new scene will be executed.
     * Try to avoid big stacks of pushed scenes to reduce memory allocation. 
     * ONLY call it if there is a running scene.
     */
    void pushScene(CCScene *pScene);

    /**Pops out a scene from the queue.
     * This scene will replace the running one.
     * The running scene will be deleted. If there are no more scenes in the stack the execution is terminated.
     * ONLY call it if there is a running scene.
     */
    void popScene(void);

    /** Replaces the running scene with a new one. The running scene is terminated.
     * ONLY call it if there is a running scene.
     */
    void replaceScene(CCScene *pScene);

This seems to be what I’m talking about with the pushing and popping of stacks of states. Except here they’re named scenes.

Still having trouble with this actually.

I would like to do:

GameScene* GameScene::GetInstance()
{
    static GameScene singleton;
    return &singleton;
}

And so when I want to run with the Scene, I can do…

pDirector->runWithScene(GameScene::GetInstance());

Or if I want to switch to the Main Menu scene, I just do…

pDirector->replaceScene(MenuScene::GetInstance());

Only thing is I don’t necessarily understand how or what the scene() function does inside my GameScene:

CCScene* GameScene::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::node();

    // 'layer' is an autorelease object
    GameScene *layer = GameScene::node();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

Is this supposed to be like, a singleton? Or what? I really only ever want 1 instance of the GameScene and the MenuScene, and I want to be able to swap between them.

Any help?

I think the constructor of GameScene may like this

 GameScene::GameScene()
{
    CCScene *scene = scene();
    scene->retain(); // because scene() return an autorelease object
}

I’m not sure what the retain() function does or how it works? Can you explain why my GameScene’s constructor would like that?

Also are scene() and node() the same thing?

And if I try to do what you wrote, it tells me “‘scene’ cannot be used as a function”.

So I’m not at my computer for the code, but I’ve been searching for things regarding this.

I’m pretty sure I understand the difference between scene() and node(). node() just adds it to the grand scheme of things and scene() sets up the node()’s and returns a scene.

I guess, is the scene that scene() returns the potential singleton? Do I need to add a static CCScene* m_pGameSceneSingleton = NULL; in the GameScene.cpp? And then just have a GetInstance() function that does

CCScene* GameScene::GetInstance()
{
    if(m_pGameSceneSingleton == NULL)
        m_pGameSceneSingleton->scene();

    return m_pGameSceneSingleton;
}

So when I have the GameScene and the MenuScene, I can have that function for both (separate code though) and when I’m in AppDelegate.cpp I just do pDirector->runWithScene(GameScene/MenuScene::GetInstance()); instead of:

// create a scene. it's an autorelease object
CCScene *pScene = GameScene::scene();

// run
pDirector->runWithScene(pScene);

Is this correct?

(Where I’m getting this all from is from… Here and Here)