Dissecting hello world example

Hi,

First of all, many thanks to the maintainers of cocos2d-x for this magnificent multi-platform port of objective-c cocos2d.
I’m no expert nor a noob in C++, but not that experienced and have been porting a android game to cocos2d-x, and so far so good :slight_smile:

However I’ve some difficulties understanding/dissecting the hello world example, which I assume is where practically everyone starts with.

For example:

  • For simplicity, I would expect that HelloWorldScene would inherit from CCScene, but instead it inherits CCLayer.
    Where the CCScene instance is actually achieved from a static member from that class.
    Q) What’s the advantage of this, only to have a scene available as static method pointer value ?

  • What’s the need/usage of the do/loop in HelloWorldScene::scene() and HelloWorldScene::init() methods ?

  • Regarding the static method which returns a pointer to the new scene instance.
    Tried to create a BaseScene with the moving the scene() method which would be inherited from HelloWorldScene, and so on.
    But like this way, only get black screen when running the scene which inherited it. (I guess this is a pure C++ noob question)

CCScene* BaseScene::scene()
{

 CCScene * scene = NULL;
 do 
 {
  // Create scene
  scene = CCScene::create();
  CC_BREAK_IF(! scene);

  // Create layer
  BaseScene*layer = BaseScene::create();
  CC_BREAK_IF(! layer);

  // Add layer to scene
  scene->addChild(layer);
 } while (0);

 // return the scene
 return scene;
}

Still nobody answered my noob questions above : /

Regarding the third item, figured it out myself.
It was kind of obvious. So BaseScene::scene is a static method, and cannot be overridden.
Meaning that when inherited it will always create a BaseScene layer:

// Create layer BaseScene*layer = BaseScene::create();

The solution is to use CRTP pattern, by using the class itself as template argument.

USING_NS_CC;

// add template definition and argument
template 
class BaseScene : public CCLayerColor
{
public:

    static CCScene* scene()
    {
        CCScene * scene = NULL;
        do 
        {
            scene = CCScene::create();
            CC_BREAK_IF(! scene);

            // Use template argument instead of BaseScene
            Derived *layer = Derived::create();
            CC_BREAK_IF(! layer);

            scene->addChild(layer);
        } while (0);

        return scene;
    }

    // Use template argument instead of BaseScene
    CREATE_FUNC(Derived);
};

And when subclassing use the following format

class HelloWorldScene : public BaseScene<HelloWorldScene>

instead of

class HelloWorldScene : public CCLayerColor

  1. I agree with you, it looks a little confusing when a Layer is called Scene. You can think of HelloWorldScene as a scene which is implemented as a layer. Actually they both inherit CCNode but have some difference: CCScene can be passed to CCDirector, CCLayer can handle touch input.
  2. The need of do{}while(false) loop is ability to instantly stop executing it’s content and jump to instruction following it (using CC_BREAK_IF). Common usage example is detecting when one of needed objects can’t be created.

Ah, thank makes sense.
Thanks Igor