いんわんのブログ

enchant.jsの音の再生とBGMのループのやり方

キュピーン

音の再生のやり方

enchant.jsでは音を鳴らす基本的な方法はこんな感じになってます。

var sound = core.assets['bomb.mp3'].clone();
sound.play();

これで音が鳴ります。clone()は複製する処理で、なくても音は鳴らせますが同じ音を重ねて鳴らすことができません。

 

音を鳴らしたい場所に上の2行を書けばいくらでも音を鳴らせるんですが、同じ音を鳴らすならデータの引き当ては一回で済ませたいところです。

 

ということで、以下のようなクラスを作ってみました。

var SoundEffect = enchant.Class.create({
    //ファイルセット関数(引数:ファイル、オブジェクト作成数(※必ず1以上))
    set: function(data, max){
        this.sound = [];//サウンドオブジェクト保存用
        this.count = 0;//カウント用初期化
        this.max = max;//同時再生最大数
        for(var i = 0; i < this.max; i++){
            this.sound[i] = data.clone();    
        }
    },
    //再生関数(クローンを順繰りに再生) 
    play: function(){
        this.sound[this.count++].play();
        if(this.count >= this.max){
            this.count = 0;
        }
    }
});

set()で引数に音楽データとともに同時再生数の限度数も渡します。これで必要な数のクローンを先に作ってしまいます。

 

再生時は順繰りにデータを再生します。しかし、同時再生数が最大数になるとそれ以上再生できなくなり、鳴っている音が消えて再生可能な空きが出るまで次の再生が始まりません。

 

クローンを作る数は敵キャラの爆発など同時再生が多発するものは多く、あまり同時に発生しない効果音は少な目に作ると良いと思います。

 

ただし、一度再生するだけなら一番最初に説明した2行で十分です。必要に応じて使ってください(‘ω’)ノ

 

BGMの再生とループのやり方

基本的には効果音の鳴らし方と同じですですが、BGMということでただ音を鳴らすだけではなく必要な機能も一緒に作ります。

 

var sound = core.assets['bgm.mp3'];
sound.play();

上記の方法では1回最後まで再生するとそこで音楽再生が終わってしまいます。ゲームのBGMなのだから自動でループ再生してくれないと困りますねよね。

 

ってことでBGMのループ再生を可能にしてくれる方法がこちら。

var Bgm = enchant.Class.create({
    initialize: function(){
        this.data = null;
        this.isPlay = false;//プレイの状態フラグ
        this.isPuase = false;
    },
    //BGM用音楽ファイルのセット
    set: function(data){
        this.data = data;
    },
    //再生(再生のみに使う)
    play: function(){
        this.data.play();
        this.isPlay = true;
        if(this.data.src != undefined){//srcプロパティを持っている場合
            this.data.src.loop = true;
        }
    },
    //ループ再生(必ずループ内に記述すること) PCでのループ再生で使う
    loop: function(){
        if(this.isPlay == true && this.data.src == undefined){//再生中でsrcプロパティを持っていない場合
            this.data.play();
            this.isPuase = false;//ポーズ画面から戻った場合は自動的に再生を再開させるため
        }else if(this.isPuase){//srcあり場合でポーズ画面から戻ったとき用
            this.data.play();
            this.data.src.loop = true;//ポーズするとfalseになるっぽい(確認はしていない)
            this.isPuase = false;
        }
    },
    //再生停止(曲を入れ替える前は,必ずstop()させる)
    stop: function(){
        if(this.data != null){
            if(this.isPuase){
                this.isPlay = false;
                this.isPuase = false;
                this.data.currentTime = 0;
            }else if(this.isPlay){
                this.data.stop();
                this.isPlay = false;
            }
        }
    },
    //一時停止(ポーズ画面などの一時的な画面の切り替え時に音を止めたいときのみ使う)
    pause: function(){
        if(this.data != null){
            this.data.pause();
            this.isPuase = true;
        }
    }
});

 

srcというプロパティがある場合と無い場合で処理を変える必要があります。

srcプロパティを持っているブラウザでは

this.data.src.loop = true;

この一行を再生時に書いておくだけで自動でループ再生してくれます。問題はsrcプロパティが無い場合です。

 

srcプロパティが無い場合ではメインループの中にplay()メソッドを書いておく必要があります。ただし、直接メソッドを書いてしまうとトラブルを引き起こします(演奏停止したいけどplay()メソッドのせいで停止できない、とか)。

 

なので演奏状態を管理するフラグを用意して再生中のみにループ再生してくれるようにしました。

loop: function(){
    if(this.isPlay == true && this.data.src == undefined){
        this.data.play();
    }
}

名前もloopにして何をしてる処理か一目瞭然ですね。

 

あと、stop()メソッドなんですが、iPhoneでは演奏していない状態でstop()メソッドを実行するとエラーが出て止まってしまいます。それを避けるためにちょっと面倒臭いことになっています。

 

関連記事