🐷

JS で効果音を最適化してみた。

に公開

短い時間で複数回鳴らすような効果音がある。
これをどう実装するか。
二つの選択肢によってそれは解決できる。

一つは、毎回生成しなおす。
これが一番簡単。

二つ目が、一つのAudioを使いまわす場合。

これは、短い時間で実行しなおすと、音がぶつ切りになる。

audioを生成する場合、その読み込み時間が発生する。

そのため、これを解決する方法を考えた。

最初に複数のAudio要素を作成しておき、それを配列に保管。
呼び出されたら、indexを変えながら再生していく仕組みを作成しました。

これにより、動的読み込みによる処理負荷、
毎回生成する部分での処理軽減ができるのではないかと踏んでいる。

この配列に格納し、毎回空いているものを再生する仕組みは、
ゲームの開発手法を参考にしている。

この関数は、asyncの関数内で実行するようにしてください。

普通に使う場合は、jsの最初に、以下の文章をコピペして、 「 export 」を消してください。

コメントアウトの部分のコードを書いて使用してください。

export class AudioPool {
  constructor(soundFilePath, poolSize) {
    this.soundFilePath = soundFilePath;
    this.poolSize = poolSize;
    this.pool = []; // オーディオオブジェクトを格納する配列
    this.currentIndex = 0; // 次に再生するオブジェクトのインデックス

    this._initializePool();
  }

  // プールを初期化し、指定された数のオーディオオブジェクトを作成する
  _initializePool() {
    for (let i = 0; i < this.poolSize; i++) {
      const audio = new Audio(this.soundFilePath);
      this.pool.push(audio);
    }
  }

  // プールからオーディオオブジェクトを取得し、再生する
  play() {
    const audio = this.pool[this.currentIndex];

    // 現在再生中のオブジェクトがあれば、最初に戻す
    audio.pause();
    audio.currentTime = 0;
    
    // 再生を開始
    audio.play().catch(e => {
      // ユーザーインタラクションがない場合のエラーをキャッチ
      console.error("Audio playback failed:", e);
    });

    // 次の再生のためにインデックスを更新
    this.currentIndex = (this.currentIndex + 1) % this.poolSize;
  }
}

// --- 使用例 ---
// プールサイズ3でオーディオプールを作成
//const soundEffectPool = new AudioPool('page_sound.mp3', 3);

// ボタンクリックでプール内のオーディオを順番に再生
//document.getElementById('play_button').addEventListener('click', () => {
 // soundEffectPool.play();
//});

Discussion