HTML5オーディオおよびゲーム開発:ブラウザーのバグ、問題と解決策、アイデア

このトピックでは、ゲームを開発する際にさまざまなブラウザーで<audio>タグを使用することの微妙さ、遭遇した問題、およびそれらを解決する方法について説明します。 説明は、便利な作業のためのラッパーの作成と並行して行われます。





Audio要素には非常に美しいインターフェイスがありますが、拡張する必要があるため、ラッパーを作成します。

var LibCanvasAudio = function ( file ) {

this . audio = new Audio ;

this . audio . src = file ;

};



LibCanvasAudio . prototype = {};








.ogg vs .mp3



手始めに-サポートされているコーデックのかす。 ほとんどのブラウザはogg vorbisをサポートしています( LinuxのOperaの場合、 gstreamerベースと優れたプラグインをインストールすることを忘れないでください)が、たとえば、Appleは脱出します。 健全なブラウザの場合は、.oggで提供し、他のすべてのブラウザでは.mp3で提供します。 ファイル名のすべての星は、それぞれoggまたはmp3に置き換えられます。



var LibCanvasAudio = function ( file ) {

this . audio = new Audio ;

this . src ( file );

};



LibCanvasAudio . prototype = {

src : function ( file ) {

var
codec = this . getSupport ();

if (!
codec ) throw 'AudioNotSupported' ;

this . audio . src = file . replace (/\*/ g , this . getSupport ());

this . audio . load ();

return
this ;

},

getSupport : function () {

return !
this . audio . canPlayType ? false :

this . audio . canPlayType ( 'audio/ogg;' ) ? 'ogg' :

this . audio . canPlayType ( 'audio/mpeg;' ) ? 'mp3' : false ;

}

}










ガトリングスキーム



いいね メインのトピックに来ます。 アクションゲームを開発しているとしましょう。 膨大な数の爆発、ショットなどがあります。 エコーのある爆発が5秒続き、爆発の間隔が0.5秒であるとします。 ファイルを最初から開始するだけの場合、前の爆発は突然中断します。 開始する前に毎回Audio要素を複製することもできますが、この方法で多数のDOM要素を作成します。 5分間のゲームの後、すべてのブラウザーが夢中になります。 したがって、 ガトリングスキームを使用することを提案します。 特定の数の要素を配列に入れ、順番に呼び出します。 最後の要素を再生しながら、最初の要素を終了する時間があります。 主なことは、各サウンドに十分な数の「トランク」を設定することです。



LibCanvasAudio . prototype = {

// ...

cloneAudio : function () {

audioClone = this . audio . cloneNode ( true );

audioClone . load ();

return
audioClone ;

},

gatling : function ( count ) {

this . barrels = [];

this . gatIndex = 0 ;

while (
count --) {

this . barrels . push ( this . cloneAudio ());

}

return
this ;

},

getNext : function () {

var
elem = this . barrels [ this . gatIndex ];

++
this . gatIndex >= this . barrels . length && ( this . gatIndex = 0 );

return
elem ;

},

playNext : function () {

var
elem = this . getNext ();

elem . pause ();

elem . currentTime = 0 ;

elem . play ();

return
this ;

}

};










取得するインターフェイスは次のようなものです。

var shotSound = new LibCanvasAudio ( 'explosion.*' ). gatling ( 6 );



window . addEventListener ( 'keydown' , function ( e ) {

(
e . keyCode == keys . SPACE ) && shotSound . playNext ();

},
false );








オペラ座のBu



オペラで、私たちは残念を待っています。 この質問を詳細に検討した結果、コードDSK-309302で報告したバグを発見しました。 Operaで複製されたAudio要素は動作しません:



// var audioOrig = document.createElement('audio'); // :

var audioOrig = new Audio ();

audioOrig . src = 'shot.ogg' ;

audioOrig . controls = 'controls' ;



var audioClone = audioOrig . cloneNode ( true );



function
appendToBody ( node ) {

document . getElementsByTagName ( 'body' )[ 0 ]. appendChild ( node );

}



audioOrig . play (); //

audioClone . play (); //



appendToBody ( audioOrig ); //

appendToBody ( audioClone ); //








Operaの小さな修正を書きましょう。

LibCanvasAudio . prototype = {

// ..

cloneAudio : function () {

if (
window . opera ) { // Reported Opera bug DSK-309302

var audioClone = new Audio ;

audioClone . src = this . audio . src ;

} else {

audioClone = this . audio . cloneNode ( true );

}

audioClone . load ();

return
audioClone ;

},

// ..

};








Foxのバグ



firefox 3.5の別のバグを見ることができます(3.6と4はすでになくなっています)-オーディオトラックが繰り返されると、最初の±が複製されます。 どうやら、私だけでなく、「ボタンを2回押すと、Firefoxで「badumm」を2回再生します 。」 ( バグを録画したビデオ )。 小さな修正を追加-オーディオを先頭ではなく25ミリ秒に巻き戻します(最小値は実験的に設定され、約0.021〜0.022秒です)。 必要に応じて、バージョンチェックを追加し、3.5以外のすべてを3.5に戻すことができます(ただし、25ミリ秒とゼロの違いは感じられません。最悪の場合、このニュアンスを知っているので、お気に入りのオーディオエディターですべてのオーディオを25ミリ秒左に移動できます)。



LibCanvasAudio . prototype = {

// ..

playNext : function () {

var
elem = this . getNext ();

elem . pause ();

elem . currentTime = 0.025 ;

elem . play ();

return
this ;

}

};








ボーナス



ie9プレビュー4では、 new Audio()



は機能しませんが、 document.createElement('audio');



置き換えることで簡単に解決できdocument.createElement('audio');







最後に何が起こったのか(スペースで突く)



結果のソースコード: pastebin.com/xG4mhX3w



All Articles