モーリーのメモ

アプリ開発等(プログラミング、CG作成)、興味を持ったことを実践してまとめるブログです。

モーリーのメモ

Cocos Studio 2によるアニメーションの作成 その2(完):Cocos2d-x v3.7(JavaScript)

 前回の記事『Cocos Studio 2によるアニメーションの作成 その1:Cocos2d-x v3.7(JavaScript) - モーリーのメモ』の続きです
 
 前回は『Cocos Studio 2』で『HelloCocos』プロジェクトに5つのアニメーションを作成し、『Cocos Code IDE』にパブリッシュするところまで作業しました。
 今回は作成したアニメーションを、場面やタッチイベントに応じて呼び出すためのコードを『Cocos Code IDE』で作成します。

アニメーションのアプリへの実装

実装する内容

下記の内容を実行するコードを作成します。

  • アプリ起動時に『Title_In』アニメーションを1回再生
  • 『Title_In』アニメーション再生後、『Title』アニメーションをループ再生
  • スタートボタンが押されたら、『Title_Out』アニメーションを1回再生
  • 『Title_Out』アニメーションを再生後、『Chara_In』アニメーションを1回再生
  • Chara_In』アニメーションを再生後、『Chara』アニメーションをループ再生

『resource.js』の編集

使用した画像とキャラクターのノードの『.jsonファイル』を登録します。

  1. 『Cocos Code IDE』の画面左の『Explorer』で、『srcフォルダ』にある『resource.js』をダブルクリックして開く
  2. 『resource.js』に、下記のようにリソースファイルを登録
var res = {
    HelloWorld_png : "res/HelloWorld.png",
    MainScene_json : "res/MainScene.json",
    NodeChara_json : "res/NodeChara.json", // キャラクターのjsonファイル
    title_png : "res/title.png", // タイトルの画像
    start_png : "res/start.png", // スタートボタンの画像
    chara_0_png : "res/chara_0.png", // キャラクターの画像
    chara_1_png : "res/chara_1.png", // キャラクターの画像
    chara_2_png : "res/chara_2.png" // キャラクターの画像
};

『app.js』の編集

『HelloWorldLayer』に、下記のようにコードを書き加えます。

var HelloWorldLayer = cc.Layer.extend({
    sprite:null,
    ctor:function () {
        //////////////////////////////
        // 1. super init first
        this._super();

        /////////////////////////////
        // 2. add a menu item with "X" image, which is clicked to quit the program
        //    you may modify it.
        // ask the window size
        var size = cc.winSize;

        var mainscene = ccs.load(res.MainScene_json);
        this.addChild(mainscene.node);
		
        this.runAction(mainscene.action); // アニメーションを組み込む
        mainscene.action.play("Title_In", false); // "Title_In"アニメーションを1回再生、第2引数がtrueの場合はループ再生

        var seq = cc.sequence( // 30フレーム後に"Title"を再生するシーケンスを作成
            cc.delayTime(0.5), // 30フレーム=0.5秒待機
            cc.callFunc(function(){
            mainscene.action.play("Title", true); // "Title"アニメーションをループ再生
        }, this));
        this.runAction(seq); // シーケンスを実行

        var SpriteStart = mainscene.node.getChildByName("SpriteStart"); // スタートボタンのスプライトを取得
        var flg = false; // 2重再生を防止するためのフラグ
        cc.eventManager.addListener({ // SpriteStartにタッチイベントを登録
            event: cc.EventListener.TOUCH_ONE_BY_ONE, // シングルタッチのみ対応
            swallowTouches:false, // 以降のノードにタッチイベントを渡す
            onTouchBegan:function(){ // タッチ開始時イベント
                if(flg) return false; // すでに再生している場合は処理を抜ける
                mainscene.action.play("Title_Out", false); // "Title_Out"アニメーションを1回再生
                var nodechara = ccs.load(res.NodeChara_json); // キャラクターのノードを読み込む
                nodechara.node.setPosition(320, 480); // キャラクターの位置を設定
                mainscene.node.addChild(nodechara.node); // mainsceneに追加
                this.runAction(nodechara.action); // アニメーションを組み込む
                var seq = cc.sequence( // キャラクターのアニメーションを時間差を付けて再生するシーケンスを作成
                    cc.delayTime(1), // 60フレーム=1秒待機
                    cc.callFunc(function(){
                        nodechara.action.play("Chara_In", false); // "Chara_In"アニメーションを1回再生
                    }, nodechara),
                    cc.delayTime(1.5), // 90フレーム=1.5秒待機
                    cc.callFunc(function(){
                        nodechara.action.play("Chara", true); // "Chara"アニメーションをループ再生
                    }, nodechara)
                );
                this.runAction(seq); // シーケンスを実行
                flg = true; // 2重再生防止用のフラグをtrueにする
                return true; // trueを返す
            }.bind(this), // タッチ開始時
        }, SpriteStart); // タッチイベントを追加する対象を指定

        return true;
    }
});

 前のアニメーションが終わった後に、次のアニメーションを再生するように、時間差を付けて再生するシーケンスを作成しています。
 アニメーションは全て60fps(1秒間に60フレーム)で作成しています。作成したアニメーションのフレーム数から待ち時間を計算しています。

アニメーションの再生

 アニメーションを再生するために必要なコードです。

var mainscene = ccs.load(res.MainScene_json); // 『.jsonファイル』を読み込む
this.addChild(mainscene.node); // オブジェクトを現在のノードに加える
this.runAction(mainscene.action); // アニメーションを組み込む
mainscene.action.play("Title_In", false); // "Title_In"アニメーションを1回再生、第2引数がtrueの場合はループ再生

 『Cocos Studio 2』で作成したシーンやノード等の情報は『.csdファイル』に保存されています。アニメーションのデータも含まれています。
 プロジェクトをJavaScript向けにパブリッシュすると、各『.csdファイル』に対応した『.jsonファイル』が作成されて『res』フォルダ内に出力されます。
 『ccs.load()』 でアニメーションの情報を含んだ『.jsonファイル』を読み込み、『〜.addChild()』でシーンやレイヤーに追加し、『〜.runAction()』でアニメーションを組み込むまでが準備段階です。
 あとは『〜.play()』でアニメーションが再生されます。

フレームの範囲を指定してアニメーションを再生

 『〜.play()』は、名前でアニメーションを指定しますが、下記のようにフレームの範囲を指定してアニメーションを再生することもできます。

mainscene.action.gotoFrameAndPlay(0, 30, false); // フレームの範囲を指定してアニメーションを再生

 この関数の引数は『〜.gotoFrameAndPlay(開始フレーム番号, 終了フレーム番号, trueでループ再生)』です。

デモ

 今回作成したものです。
http://githubmorley.github.io/cocosprojects-pages/hellococos04/
 タイトルがアニメーション表示され『Start』ボタンが点滅します。
 『Start』をクリックするとタイトルが消えてキャラクターが表示されます。
 
以上です。

あとがき

 『Cocosでこれをやる関数はどれだ〜?』と探している時はなかなか情報が出てこないんですが、やっと関数名がわかって、その関数名で検索すると親切に説明してくれているページがたくさん出てくるんですよね。