読者です 読者をやめる 読者になる 読者になる

モーリーのメモ

プログラミングやCG作成等、アプリ開発を中心に情報を収集中!

ジョイスティックでキャラクタを動かす!:Cocos Creator

 こちらの記事で2Dのキャラクタのアニメーションを作りました。
mmorley.hatenablog.com
 ↑ではボタンでアニメーションを切り替えていましたが、ゲームらしくするためにジョイスティックでキャラクタを動かせるようにしてみました。

使用環境

 私が使用している環境です。

  • Mac OS X El Capitan Version 10.11.4
  • Inkscape Version 0.91
  • Cocos Creator Version 1.0.3

作業の流れ

 ジョイスティックは、こちらの記事で作ったものを利用しました。
mmorley.hatenablog.com

キャラクタの動かし方

 キャラクタを動かす場合、
①:キャラクタが動く。
②:キャラクタは定位置で、背景が動く。
③:①と②の合わせ技。一定幅キャラクタが動いて、それ以上は背景が動く。
等があると思います。
 今回は②で動かします。

背景の動かし方

 ちゃんとした絵は無理なので1枚の絵をぐるぐるループで回します。
 隙間なくするために、2つにコピーして下図のようにします。
f:id:mmorley:20160518232158p:plain:w350
 この部分のスクリプトです。
 this.ground[0]とthis.ground[1]が背景となる地面です。

    // 周期処理
    update: function (dt) {
        // ジョイスティックの値を取得
        var velocity = this.joypadStick.getComponent("JoypadStick").getVelocity(); // ジョイスティックの値を取得       
        var speed = velocity.x * 6; // 移動速度
 
        var width = this.ground[0].width; // 地面の画像の幅
        this.moveX += speed; // 移動量
        var count = parseInt(this.moveX / width); // 幅何個分か計算
        var posX;
        if(count % 2 === 0){ // 偶数の場合、ground[0]にground[1]が付いて行く
            posX = this.ground[0].x; // 現在の位置を取得
            posX -= speed; // 移動後の位置
            // 画面外に出たら、反対に移動
            if(posX < -width){
                posX = width;
            }
            if(posX > width){
                posX = -width;
            }
            this.ground[0].x = posX; // 地面を移動
            // 隙間を埋める位置に移動
            if(posX < 0){
                this.ground[1].x = posX + width;
            }else{
                this.ground[1].x = posX - width;
            }
        } else { // 奇数の場合、ground[1]にground[0]が付いて行く
            posX = this.ground[1].x; // 現在の位置を取得
            posX -= speed; // 移動後の位置
            // 画面外に出たら、反対に移動
            if(posX < -width){ 
                posX = width;
            }
            if(posX > width){
                posX = -width;
            }
            this.ground[1].x = posX; // 地面を移動
            // 隙間を埋める位置に移動
            if(posX < 0){
                this.ground[0].x = posX + width;
            }else{
                this.ground[0].x = posX - width;
            }
        }
    }, 

 移動距離を地面の幅(=画面の幅)で割って
 商が偶数の場合はthis.ground[0]を動かしてthis.ground[1]が付いて行く
 奇数の場合はthis.ground[1]を動かしてthis.ground[0]が付いて行く
 ようにしました。

キャラクタのアニメーションの切り替え

 移動速度によって、歩く、走る、止まるのアニメを切り替えます。
 この部分のスクリプトです。

    // 周期処理
    update: function (dt) {
        // ジョイスティックの値を取得
        var velocity = this.joypadStick.getComponent("JoypadStick").getVelocity(); // ジョイスティックの値を取得
        
        var speed = velocity.x * 6; // 移動速度
        var runSpeed = 4; // Run速度
        // アニメーション再生
        switch (this.seq) {
            case Seq.Idle: // idle実行中
                if(Math.abs(speed) >= runSpeed){ // run速度以上の場合
                    this._animation.play("run"); 
                    this.seq = Seq.Run;
                    break;
                }
                if(Math.abs(speed) > 0){ // 速度が0でない場合
                    this._animation.play("walk"); 
                    this.seq = Seq.Walk;
                    break;
                }
                break;
            case Seq.Walk: // walk実行中
                if(Math.abs(speed) >= runSpeed){ // run速度以上の場合
                    this._animation.play("run"); 
                    this.seq = Seq.Run;
                    break;
                }
                if(Math.abs(speed) === 0){ // 速度が0の場合
                    this._animation.play("idle"); 
                    this.seq = Seq.Idle;
                    break;
                }
                break;
            case Seq.Run: // run実行中
                if(Math.abs(speed) === 0){ // 速度が0の場合
                    this._animation.play("idle"); 
                    this.seq = Seq.Idle;
                    break;
                }
                if(Math.abs(speed) < runSpeed){ // run速度より遅い場合
                    this._animation.play("walk"); 
                    this.seq = Seq.Walk;
                    break;
                }
                break;
        }

        // キャラクターの向き
        if(speed >= 0){
            this.character.setScale(1, 1); // 右向き
        } else {
            this.character.setScale(-1, 1); // 左向き(X方向反転)
        }
    },

 キャラクタの状態と速度の変化によって、再生するアニメーションを分けています。
 キャラクタの向きはスケール値で反転しました。

デモ

 上記を実装したデモです。
 ジョイスティックの倒し加減で速度が変わります。
 上下は無視しています。
 ゴールも何もありません。

あとがき

 キャラクタにジャンプや他のアクションを追加したら、アニメーションの条件分岐がすごいことになりそうです。