× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。 |
cocos2d-xで、LayerとかSpriteを継承して新しいクラスを作る場合がある。
たとえば画面を作りたいなら、Layerを継承すればいい。cocosプロジェクトを作ったときもコード中にHelloWorldSceneがそうして作られているし、それを真似すればいい。 基本的にゲーム中のオブジェクトなら、Layerを継承して作るのが良さそうだ。 前の記事も参照。 その他にも、たとえばキャラクターなら、Spriteを継承して作るなど、内容に応じていろいろなクラスを継承して作るのが良い。 以下はLayerを継承して作った例
こうすると、コード中にnewもdeleteも現れなくなる。 cocos2d-xの作法にあった形になる。 static関数のcreate() は、CREATE_FUNCマクロによって生成されている。 CREATE_FUNCマクロを使うためには、 ・引数無しコンストラクタがあること ・引数無しで戻り値がboolのinit()という関数を持っていること ・そのクラスがRefを継承していること(より正確には、autorelease()という関数を持っていること) が必要。
純粋なデータ構造を扱うクラスだから、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 |
|