CocoStudio setMovementEventCallFuncとsetFrameEventCallFuncの使い方
ですので本記事の内容は古い可能性があります、ご注意ください。
新作RPGをiPhone/Android両対応でリリースするため、先月よりCocos2d-xで開発を行っていました。
んで、そろそろ戦闘画面を実装しなきゃなぁ・・・と思って、ここ数日CocoStudioっていうCocos2d-x専用のエディタソフトを使ってアニメーションの実装を進めていたんですね。
その中でアニメーション終了時やフレーム毎のコールバックを受け取る必要性が出てきたため調べてみたところ、次の関数が使えそうでした。
- cocostudio::ArmatureAnimation::setMovementEventCallFunc
→アニメーション開始時、終了時のコールバック関数。 - cocostudio::ArmatureAnimation::setFrameEventCallFunc
→CocoStudioでイベントを設定したフレームが描画される時のコールバック関数。
この2つの関数について、それぞれざっくりとですが使い方を調べてみたので、メモついでに展開しておきます。
実際の使い方
setMovementEventCallFuncの使い方
これは超カンタン。
Armature *armature = Armature::create("AnimationC01"); // Animation開始、終了時コールバック armature-> getAnimation()-> setMovementEventCallFunc([](Armature *armature, MovementEventType type, const std::string &name) { switch(type) { case MovementEventType::START: CCLog("MovementEventCallFunc START name=%s", name.c_str()); break; case MovementEventType::COMPLETE: CCLog("MovementEventCallFunc COMPLETE name=%s", name.c_str()); break; case MovementEventType::LOOP_COMPLETE: CCLog("MovementEventCallFunc LOOP_COMPLETE name=%s", name.c_str()); break; } });
こんな感じに実装して、アニメーションを実行してみたところ次のようなログが取得できました。
D/cocos2d-x debug info(30086): MovementEventCallFunc START name=waiting D/cocos2d-x debug info(30086): MovementEventCallFunc LOOP_COMPLETE name=waiting D/cocos2d-x debug info(30086): MovementEventCallFunc LOOP_COMPLETE name=waiting D/cocos2d-x debug info(30086): MovementEventCallFunc LOOP_COMPLETE name=waiting D/cocos2d-x debug info(30086): MovementEventCallFunc START name=crisis D/cocos2d-x debug info(30086): MovementEventCallFunc LOOP_COMPLETE name=crisis D/cocos2d-x debug info(30086): MovementEventCallFunc LOOP_COMPLETE name=crisis D/cocos2d-x debug info(30086): MovementEventCallFunc START name=walk D/cocos2d-x debug info(30086): MovementEventCallFunc LOOP_COMPLETE name=walk D/cocos2d-x debug info(30086): MovementEventCallFunc LOOP_COMPLETE name=walk D/cocos2d-x debug info(30086): MovementEventCallFunc LOOP_COMPLETE name=walk D/cocos2d-x debug info(30086): MovementEventCallFunc START name=damage D/cocos2d-x debug info(30086): MovementEventCallFunc COMPLETE name=damage
アニメーション名「waiting」「crisis」「walk」はそれぞれループあり、「damage」はループ無しの設定でしたが、ログを見る限り想定通り動いている感じがしますね。
ループありの場合は、アニメーション開始時のみSTARTが呼ばれて、後はLOOP_COMPLETEで終了と次の開始を判断するような感じでしょうか。
ループ無しの場合は、STARTとCOMPLETEが1回ずつ呼ばれて終了ですね。
setFrameEventCallFuncの使い方
これが何だかちょっとクセがありそうな気がします。
まず、このコールバックはデフォルトの設定では呼ばれることはありません。
以下の画像にある通り、CocoStudioのアニメーション編集画面で、コールバックを受け取りたいフレームのフレームイベント欄にユニークな文字列を設定する必要があります。
そして、次のように実装してみました。
// フレームイベント armature-> getAnimation()-> setFrameEventCallFunc([](Bone *bone, const std::string &event, int originFrameIndex, int currentFrameIndex) { CCLog("FrameEventCallFunc event=%s, originFrameIndex=%d, currentFrameIndex=%d", event.c_str(), originFrameIndex, currentFrameIndex); });
すると、こんな感じにログが取得できました。
D/cocos2d-x debug info(32069): FrameEventCallFunc event=waitingkaisidayo, originFrameIndex=0, currentFrameIndex=0 D/cocos2d-x debug info(32069): MovementEventCallFunc START name=waiting D/cocos2d-x debug info(32069): FrameEventCallFunc event=waitingowaridayo, originFrameIndex=60, currentFrameIndex=61 D/cocos2d-x debug info(32069): MovementEventCallFunc LOOP_COMPLETE name=waiting D/cocos2d-x debug info(32069): FrameEventCallFunc event=waitingkaisidayo, originFrameIndex=0, currentFrameIndex=1 D/cocos2d-x debug info(32069): FrameEventCallFunc event=waitingowaridayo, originFrameIndex=60, currentFrameIndex=60 D/cocos2d-x debug info(32069): MovementEventCallFunc LOOP_COMPLETE name=waiting D/cocos2d-x debug info(32069): FrameEventCallFunc event=waitingkaisidayo, originFrameIndex=0, currentFrameIndex=1 D/cocos2d-x debug info(32069): FrameEventCallFunc event=waitingowaridayo, originFrameIndex=60, currentFrameIndex=60 D/cocos2d-x debug info(32069): MovementEventCallFunc LOOP_COMPLETE name=waiting
今回は「waiting」アニメーションの内、最初と最後のキーフレームにそれぞれ「waitingkaisidayo」「waitingowaridayo」と設定してみたのですが、まぁ想定通りコールバックが返って来ていますね。
てーか、originFrameIndexの値も確かに「waiting」アニメーションは合計60フレームで作っているので正しいような気にさせられますが、アニメーション開始時の値がゼロになってるんで、やっぱり使い物にならない気もする?
「合計60フレームの内の1フレーム目ですよー」的なアナウンスがされる物だと勝手に思ってたんですが、この辺りはもう少しちゃんと調べないといけませんね・・・。
何はともあれ、使えることは使えそう
というかこれを使うしかないんですけど、とにかくCocoStudioで作ったアニメーションのコールバック処理はsetMovementEventCallFuncとsetFrameEventCallFuncを使うことで何とかなりそうです。
ちなみに、上記のようなラムダ式ではなく、次のような感じでメンバ関数をコールバック関数として指定することもできるようです。多分。
メンバ関数の定義
void HelloWorld::onMovementEvent(Armature *armature, MovementEventType type, const std::string &name) { // 処理を記述 } void HelloWorld::onFrameEvent(Bone *bone, const string &event, int originFrameIndex, int currentFrameIndex) { // 処理を記述 }
コールバックの指定
armature-> getAnimation()-> setMovementEventCallFunc(this, movementEvent_selector(HelloWorld::onMovementEvent)); armature-> getAnimation()-> setFrameEventCallFunc(this, frameEvent_selector(HelloWorld::onFrameEvent));
でも、間違ってたらごめんなさい。
ぶっちゃけ、日本語の情報少なすぎてよく分からないのさっ!ヽ(゚∀゚)ノ パッ☆
開き直ったところで、本日はお開きです。誰か開発手伝ってちょーだい・・・。
GooglePlayのランキングから除外される件で検索をしていたところ、こちらのブログにたどり着きました。
一人で開発されているということで、私と同じ境遇なので共感しました。絵もプログラムもデザインもテキストも、となると仕事量もおおくて大変ですよね。よくわかります…!
でも絵もとても素敵ですね!そちらが本業なのかな?と思ったほどです。
またブログ拝見しにきます^^
> 通りすがりさん
こんにちは、コメントありがとうございます。
年始からフルスロットルで稼働してたもので、気付くのに遅れました。どうもすみません。
死ぬ気で働いたおかげで、ギリギリ2月中にはリリースできるかな?って感じです。
またいらしてください、ぜひ情報交換など兼ねて交流しましょう^^