Search code examples
c++cocos2d-xcocos2d-x-3.0scene

How to alternate between two scenes in cocos2d-x?



I'm creating a game using Cocos2d-x. I'm currently creating a gameover menu, in that menu I need to be able to switch to both my menuscene and my gamescene (When I say switch to gamescene I only really only mean "to restart" the game). But circular dependencies stop me from being able to do this.
MenuScene needs to be able to useGameScene::create() in order to switch to the gamescene and the gameover menu needs to be able to use both of GameScene::create() or its restart funtion and MenuScene::create() which is giving me circular dependency problems
I can't separate my gameover menu to it's own file as I still need the GameScene dependency and GameScene would need gameover.
I can't combine them as GameScene then needs to depend on MenuScene

So my question is: How do I alternate between two scenes in cocos2d-x c++.

I read somewhere about pushing and popnig scenes in Director, but I don't really understand how that works, or if I could use that for my purpose.
Thank you in advance!

EDIT:
Now that I think about it, could I not just push mMenuScene to Director before switching to GameScene? That should work if I understand that push/pop mechanic correctly.


Solution

  • I think you might have a misconception of how complex this is, using the way I provided below you can and should definitely split your game over scene into its own file.

    The scene replace is easy enough, just use the code below:

    Including your file:

    #include "MainGameScene.h"
    

    Creating and switching scenes in your onClickListener:

    auto gameOverScene = GameOverScene::createScene();
    
    // use code below for hard replace
    Director::getInstance()->replaceScene(gameOverScene );
    
    // or use code below for transition fade replace
    Director::getInstance()->replaceScene(TransitionFade::create(1, gameOverScene , Color3B(255, 255, 255)));
    

    As for the restart functionality. I usually provide a callback to my game over scene that I call when the restart button has been clicked. Not that I ever swap out my scene completely for a mobile game over scene, but I still do it the same way regardless. So lets do steps (This assumes you seperated your game over scene into it's own file named GameOverScene :) ).

    1. Store a function pointer in your GameOverScene.h to your reset method in MainGameScene:

      std::function<void()> _resetCallback;
      
    2. Set your function pointer from the main game scene, before running with the GameOverScene.

      auto gameOverScene = GameOverScene::createGameOverScene();
      gameOverScene->setResetCallback(std::bind(&MainGameScene::reset, this));
      
    3. When your reset button is clicked, call the _resetCallback

      void GameOverScene::onResetClicked(Ref* sender)
      {
        _resetCallback();
      }
      

    This should provide you with all the functionality you need to set up a what you want as well as remove the circular dependency that you have. I have used this way many times before and it always works. Let me know if this solution works for you.