短いですが、今回の記事は、昨日書こうとしたけど寝落ちしてしまって書けなかったことです。
最近の悩み
cocos2d-xで、ここ最近上手くいっていないことがありました。 それは、タッチ操作を実装したCCLayerクラスでCCActionが実行できないことです。 他のCCLayerで同じ記述をした時には、上手くCCActionが動いていたので、どうしてこうなるのか悩んでいました。
CCLayer単独ではCCActionが使えない
まず考えたのが、「CCLayerクラス単独ではCCActionが使えないのではないのか?」ということ。 私がここまで目に触れてきたcocos2d-xのコードでは、HelloWorldのテンプレートで利用されている用に、CCLayerクラスの中にCCSceneを併記して構成されているものばかりで、CCActionクラスは、このようにしないと作動しないのではないかと考えました。 [c] //こんな感じです。 CCScene HelloWorld::scene() { CCScene scene = CCScene::create(); HelloWorld *layer = HelloWorld::create(); scene->addChild(layer,0); return scene; } [/c]
複数のレイアーではCCActionが利用できない
cocos2d-xの公式サイトのCCSceneやCCLayerの説明の所に、こんな図が載っています。 Cocos2d-x | Director Scene Layer and Sprite
もしかしたら、複数のレイアーは利用できるが、機能は一つのレイアーにつき1つだけなのか? 例えばこんなふうに、レイアーごとでできることが決まっているのかもしれない。
- タッチ操作ができるレイアー
- アニメーションを担当するレイアー
- メニューを担当するレイアー
タッチ操作とCCActionは同じレイアーで利用できない
これが一番あやしいと思い、ずーっと考えていました。 タッチ操作ができるレイアーでは、CCActionができない。
こんなふうに色々、考えてCCActionが動くように試していました。
解決
それが昨日解決しました。 とても単純なミスで、親クラスのメソッドを呼び出していなかったことが原因だったようです。
onEnter()
実はタッチ処理を行なっているレイアーで以下のようなコードを書いていました。
[c] void TouchLayer::onEnter(){
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
} [/c]
タッチ処理を有効にするために、記載をしていたのですが、CCLayerクラスにあるonEnter()メソッドが呼び出されていなかったので、CCActionが動かなかったみたいです。 [c] void TouchLayer::onEnter(){
//親クラスのメソッドを呼び出す
CCLayer::onEnter();
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
} [/c] cocos2d-iPhoneだとsuperを利用すれば親クラスを呼び出せるのですが、cocos2d-xでは使えないので、親クラスを明示してonEnter()を使います。
これで、CCActionクラスが利用できるようになりました。
タッチ操作の謎
実は、onEnter()に何も記載が無くてもタッチ処理ができます。 CCLayerを初期化する際に以下の1文があれば動きます。 [c] this->setTouchEnabled(true); [/c]
これは、このままでいいのか、getTouchDispatcher()を設置しないといけないのか、よくわからないです。 色々謎が多いcocos2d-x。もっと情報が欲しい。