Confusion over multiple scenes.

Hey everyone I’m currently loving the switch from XNA to Cocos2d-x however I’m sort of confused as to what is best practice when handling multiple Scenes in a game.

The example hello world app has the HelloWorldScene and it looks like it’s actually a CCLayer and the function scene() is what adds it? Now my scene which is actually a layer contains child layers like GameplayLayer, UILayer, FXLayer, etc. Now my real question what is the best thing to do when going from a menu scene to a game scene to a game over scene? Do I make three CCLayers that containt the scene() function, or do I need to change my architecture and start creating individual CCScenes? As I see it now there’s no reason to ever explicitly create a CCScene but I’m worried I’m missing something. Thanks!

EDIT
Just to put it simply and answer the question more directly, for the Main Menu scene, the Game scene and the Game Over scene, you do not need to create a separate class for the scenes themselves and, because of the way cocos2d-x is done, should use the classes for their related layers as well as the scene creation.
/EDIT

In AppDelegate under the applicationDidFinishLaunching() function, you will find the following:

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

// run
pDirector->runWithScene(pScene);

Using the static function “scene” creates the scene for your game, where only one scene can be running at a time. The HelloWorld class’s “init” function creates the HelloWorld layer. Your scene is not actually a layer, the layer class just contains a static function to create a scene and add the layer to it, which all layers of that scene should be added via the same method unless you want layers to be child layers of other layers (which should not usually be the case). If you have layers that are going to be child layers for a main scene that is not of the same class then no, you do not need to add the static scene() function.

You can have a layer without creating scenes, where the layers become a child of that scene or a child of other layers. The way I have setup my architecture is that I have a Main Menu scene and a Game scene. When the user starts a game is when I change the Game scene to the running scene. Here is an example of my architecture:

Root
|__ MainMenuScene              // The main menu scene
    |__ Main Menu Layer        // Contains everything main menu related
|__ GameScene                  // The in-game scene
    |__ Game Layer             // Contains everything in-game related
    |__ Heads Up Display Layer // This encapsulates all HUD features
       |__ Controls Class      // This encapsulates the controls for the HUD layer by separating it from all of the other HUD features
    |__ Game Menu Layer        // This is the pause menu for the game

Here is how my Game scene and layers are created:

bool
CGameScene::init()
{
    bool bIsInitialised = false;

    // Initialise the layer's base class
    if( CCLayer::init() )
    { // Initialise the in-game layer
        // Create and initialise the HUD; the HUD is an auto-release object so it needs to
        // be retained and later released on de-construction
        m_pHeadsUpDisplay = CHeadsUpDisplay::create();
        m_pHeadsUpDisplay->retain();

        if (m_pHeadsUpDisplay)
        {
            // Create and initialise the Game Menu; the Game Menu is an auto-release
            // object so it needs to be retained and later released on de-construction
            m_pGameMenu = CGameMenu::create();
            m_pGameMenu->retain();

            if (m_pGameMenu)
            {
                // Hide the game menu and disable touch events for the menu
                m_pGameMenu->HideGameMenu();

                // Initialisation successful
                bIsInitialised = true;
            }
        }
    }

    return (bIsInitialised);
}

cocos2d::CCScene*
CGameScene::CreateGameScene()
{
    // Declare the Game scene; the scene is an auto-release object
    CCScene* pGameScene = 0;

    // Instantiate the Game scene
    pGameScene = CCScene::create();
    if (pGameScene)
    {
        // Declare and instantiate the Game layer; the layer is an auto-release object
        CGameScene* pGameLayer = CGameScene::create();

        if (pGameLayer)
        {
            // add the Game layer to the Game scene
            pGameScene->CCNode::addChild(pGameLayer, 0);

            // add the Game layer's Heads Up Display layer to the scene with a z-order of 1 to
            // ensure that it shows on-top of the Game layer
            pGameScene->CCNode::addChild(pGameLayer->GetHeadsUpDisplay(), 1);

            // add the Game layer's Game Menu layer to the scene with a z-order of 2 to ensure
            // that it shows on-top of the Game layer and the Heads Up Display layer
            pGameScene->CCNode::addChild(pGameLayer->GetGameMenu(), 2);
        }
    }

    // return the Game scene
    return (pGameScene);
}

Here you can see that I am creating the layers inside the Game layer’s initialisation however they are actually added as childs to the Game’s scene. The reason I am doing this is because I need to be able to access the functionality to the layers and I personally avoid creating singleton access functionality myself as I am yet to find a case where it is actually necessary.

The Game scene is created/activated from within the Main Menu via the following line:
cocos2d::CCDirector::sharedDirector()->replaceScene(CGameScene::CreateGameScene());

My layer classes, other than the GameScene class and the MainMenuScene class, do not contain the scene creation functions.

Thanks Tim! I guess it’s a little different in how I envisioned it in my head as having explicit CCScenes everywhere, so I’ll have to readjust my false reality, but you put it in excellent terms. Thanks again!