忍者ブログ
  • 2024.08
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 2024.10
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

【2024/09/19 15:46 】 |
cocos2d-xのクラスを継承する
cocos2d-xで、LayerとかSpriteを継承して新しいクラスを作る場合がある。

たとえば画面を作りたいなら、Layerを継承すればいい。cocosプロジェクトを作ったときもコード中にHelloWorldSceneがそうして作られているし、それを真似すればいい。

基本的にゲーム中のオブジェクトなら、Layerを継承して作るのが良さそうだ。
前の記事も参照。

その他にも、たとえばキャラクターなら、Spriteを継承して作るなど、内容に応じていろいろなクラスを継承して作るのが良い。

以下はLayerを継承して作った例

class MyClass : public cocos2d::Layer{
//create() メソッド作成
CREATE_FUNC(MyClass);

//init()作成
bool init() override{
cocos2d::Layer::init(); //親クラスのinitを呼び出す。忘れずに!
//自前の初期化処理
//
}

//その他の定義
//
};

//生成
auto obj = MyClass::create(); //参照カウンタが1になる

//破棄
obj->release(); //参照カウンタを1減らす。0になるので後で自動的に破棄される。
obj = nullptr; //これはC++の作法通りしておいたほうがよい






こうすると、コード中にnewもdeleteも現れなくなる。
cocos2d-xの作法にあった形になる。

static関数のcreate() は、CREATE_FUNCマクロによって生成されている。
CREATE_FUNCマクロを使うためには、
・引数無しコンストラクタがあること
・引数無しで戻り値がboolのinit()という関数を持っていること
・そのクラスがRefを継承していること(より正確には、autorelease()という関数を持っていること)
が必要。


#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
__TYPE__ *pRet = new __TYPE__(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = NULL; \
return NULL; \
} \
}







純粋なデータ構造を扱うクラスだから、SceneもNodeも継承する必要が無い、と思っても
「メモリ管理の方法は統一しておくべき」という観点から、最低でもRefは継承するのがよい。
Refは自動でメモリ管理をしてくれるクラス。使用されなくなったらreleaseすれば、裏でPoolManagerが自動的に破棄する。


<<注意!>>

init()関数はNodeクラスに仮想関数として定義がある。
オーバーライドして、さらに親クラスのinit()を呼ぶのを忘れないように
Refクラスを直接継承する場合は、オーバーライドではなく新規の定義になる(Refクラスにinit()がないので)


Spriteクラスを継承して、親クラスのinit()の呼び出しを忘れた場合は、大抵バクる。
(glProgramStateがセットされないというアサートが出る。)





もうひとつ。
create()メソッドは継承はしないが、
元々create()メソッドを持っているクラスから継承した場合、自クラスで定義しなくても呼び出せるわけだ。
例えばSpriteクラスを継承してMySpriteクラスを作った場合

auto sprite = MySprite::create();
とすると、
Sprite::create()が呼び出されることになる。

ただしその場合、戻り値型はSprite*なので、

MySprite* sprite = MySprite::create();
はコンパイルエラーになる。
ちゃんとMySpriteでcreate()を定義する必要がある(CREATE_FUNC(MySprite); と書くだけ)


Spriteの場合、create()だけでなく
create(const std::string& filename)
create(const std::string& filename, const Rect& rect)
createWithTexture(Texture2D *texture)
createWithTexture(Texture2D *texture, const Rect& rect, bool rotated=false)
createWithSpriteFrame(SpriteFrame *spriteFrame)
createWithSpriteFrameName(const std::string& spriteFrameName)
と言う具合に多くのcreate()系のstaticメソッドがある。

本来であれば、MySpriteクラスにすべての同名関数を用意すべきである。
ただし、戻り値がMySprite*でなくSprite*なので、コンパイルエラーで気付けるといえば気付ける。
PR
【2014/12/24 11:37 】 | cocos2d-x | 有り難いご意見(0)
<<adcrops導入 | ホーム | cocos2d-x 3.0 の主なクラス>>
有り難いご意見
貴重なご意見の投稿














<<前ページ | ホーム | 次ページ>>