CocoStudio setMovementEventCallFuncとsetFrameEventCallFuncの使い方

2017年3月現在、私はCocos2d-xでの開発を行っていません。Unity使ってます。

ですので本記事の内容は古い可能性があります、ご注意ください。

新作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のアニメーション編集画面で、コールバックを受け取りたいフレームのフレームイベント欄にユニークな文字列を設定する必要があります。

※クリックで大きい画像を開きます。
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」と設定してみたのですが、まぁ想定通りコールバックが返って来ていますね。

ただ、currentFrameIndexの値ですが、一番最初だけ何だかバグってる気もします・・・。

てーか、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));

でも、間違ってたらごめんなさい。

ぶっちゃけ、日本語の情報少なすぎてよく分からないのさっ!ヽ(゚∀゚)ノ パッ☆

開き直ったところで、本日はお開きです。誰か開発手伝ってちょーだい・・・。

スポンサーリンク


2 Responses to “CocoStudio setMovementEventCallFuncとsetFrameEventCallFuncの使い方”

  1. 通りすがり より:

    GooglePlayのランキングから除外される件で検索をしていたところ、こちらのブログにたどり着きました。
    一人で開発されているということで、私と同じ境遇なので共感しました。絵もプログラムもデザインもテキストも、となると仕事量もおおくて大変ですよね。よくわかります…!
    でも絵もとても素敵ですね!そちらが本業なのかな?と思ったほどです。
    またブログ拝見しにきます^^

  2. フイロン より:

    > 通りすがりさん
    こんにちは、コメントありがとうございます。
    年始からフルスロットルで稼働してたもので、気付くのに遅れました。どうもすみません。
    死ぬ気で働いたおかげで、ギリギリ2月中にはリリースできるかな?って感じです。
    またいらしてください、ぜひ情報交換など兼ねて交流しましょう^^

コメントを残す

このページの先頭へ