nirasan's tech blog

趣味や仕事の覚え書きです。Linux, Perl, PHP, Ruby, Javascript, Android, Cocos2d-x, Unity などに興味があります。

cocos2d-x で scene 作成時に引数を渡せるようにする

遷移先の scene 作成時に、scene の状態を指定するために引数を渡せるようにしました。
scene に渡した引数は、初期化メソッドに引き渡されて、実装時に自由に扱えるようにします。

引数付きで CCScene* を作成するメソッド宣言のためのマクロを宣言する

  • Scene の作成時に外部から呼ばれる scene() の作成マクロを任意のファイルで宣言します。
  • 今回は GameMacros.h を作成してそこに追記しました。
  • 引数はとりあえず void* を渡して、CCScene 拡張クラスでそれぞれ実装する init(void*) の中でキャストして使う想定です。
  • 実装にあたり、CREATE_FUNC マクロを宣言している CCPlatformMacros.h を参考にしました。
/*
 void*を引数にとるscene関数を宣言する
 引数はcreateからinitに引き渡される
 CREATE_FUNCの宣言は不要になる
 */
#define SCENE_FUNC_WITH_ARG(__TYPE__) \
static CCScene* scene(void* arg) \
{ \
    CCScene* scene = CCScene::create(); \
    __TYPE__* layer = __TYPE__::create(arg); \
    scene->addChild(layer); \
    return scene; \
} \
CREATE_FUNC_WITH_ARG(__TYPE__);

/*
 void*を引数にとるcreate関数の宣言
 引数はinitに引き渡される
 */
#define CREATE_FUNC_WITH_ARG(__TYPE__) \
static __TYPE__* create(void* arg) \
{ \
    __TYPE__ *pRet = new __TYPE__(); \
    if (pRet && pRet->init(arg)) { \
        pRet->autorelease(); \
        return pRet; \
    } \
    else { \
        delete pRet; \
        pRet = NULL; \
        return NULL; \
    } \
}

CCScene 拡張クラスでマクロの呼び出しと init(void*) の実装

  • CCScene 拡張クラスのヘッダーでマクロを呼び出します。
  • 今回は GameScene というクラス名だとします。
class GameScene : public cocos2d::CCLayer
{
public:
    virtual bool init(void* arg);
    SCENE_FUNC_WITH_ARG(GameScene);
};

CCScene 拡張クラスで引数を受け取る初期化メソッドの実装

  • GameScene.cpp で init(void* arg) を実装します。
bool GameScene::init(void* arg)
{
    if (!CCLayer::init()) {
        return false;
    }
    
    /*
     引数を展開して、int 型のインスタンス変数 level に代入する場合
     */
    level = *((int*)arg);

    return true;
}