not good but great

プログラミング、アート、映画・本の感想について書きます。

Web Audio APIを使ってゲームの効果音を作成する

今までに作ったブロック崩し

最近はブロック崩しを作っていました。
Javascriptでブロック崩しを作ったよ - not good but great

玉の数を増やしたりしてました
hitOptionsを使い当たり判定を厳密にし、弾丸同士を完全弾性衝突させる - not good but great

問題

しかし音がないので少し盛り上がりに欠けていました。

Web Audio APIで音をつける

以下の記事を読んで、WebAudio APIで音をつけれそうだとわかりました。
Getting Started with Web Audio API - HTML5 Rocks
Web Audio API 解説 - 06.バッファソースでワンショットサンプルから音を出す | g200kg Music & Software

Garage Bandを使う

効果音の作成はGarage Bandを使いました。全く使い方がわからないので、ドラムの単発音だけ録音しました。本当はその音を加工して、かっこよくしたいと思いましたが、やり方がわからなかったので諦めました笑。

demo


弾がブロックに当たると効果音が出ます。

コード

コードはこちらのリンク先のコードをパクりました参考にしました。
[Web Audio API 解説 - 06.バッファソースでワンショットサンプルから音を出す | g200kg Music & Software

if(typeof(webkitAudioContext)!=="undefined"){
    var audioctx = new webkitAudioContext();
}else if(typeof(AudioContext)!=="undefined"){
    var audioctx = new AudioContext();
} 

Web Audio APIではAudioContextを使って音を管理します。このあたりのことはまだよくわかっていません。

var buffer = null;
LoadSample(audioctx, "http://jsrun.it/assets/5/v/G/M/5vGMS.mp3");
 
function LoadSample(ctx, url) {
    //XHRで読み込み
    var req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.responseType = "arraybuffer";
    req.onload = function() {
        if(req.response) {
//          buffer = ctx.createBuffer(req.response, false);
            ctx.decodeAudioData(req.response,function(b){buffer=b;},function(){});
        }
        else
            buffer = ctx.createBuffer(VBArray(req.responseBody).toArray(), false);
    }
    req.send();
}

XHRで返ってくるデータ形式を"arraybuffer"にしているのは、音声データがテキストではないからです。そして受信したデータをdecodeAudioDataでデコードします。
・ArrayBuffer
ArrayBuffer - JavaScript | MDN

バッファとは?

そもそもバッファという言葉がわかっていませんでした。

複数の機器やソフトウェアの間でデータをやり取りするときに、処理速度や転送速度の差を補うためにデータを一時的に保存しておく記憶装置や記憶領域のこと。

バッファ(buffer)とは - IT用語辞典 e-Words

上のリンクを読んでみると、一時的な記憶領域ということみたいです。

function Play() {
    var src = audioctx.createBufferSource();
    src.buffer = buffer;
    src.connect(audioctx.destination);
    src.start(0);
}

これで効果音を再生します。

//レンガに対する弾丸の当たり判定
for(var i = 0;i < brickChildren.length;i++){
    var hitResult2 = brickChildren[i].hitTest(bullets[j].path.position,hitOptions);

    if(hitResult2){
        //跳ね返る
        bullets[j].vy *= -1;
        //効果音再生
        Play();
        //レンガ消滅
        brickChildren[i].remove();
    }
}

再生するタイミングはレンガに弾丸が当たったときにしています。

これからの展望

GarageBandでかっこいい音をつくるか、Web Audio APIで音の流し方を工夫するかして、もう少しクオリティを上げてみたいです。