JavaScript»ゲーム制作»リソースの読込 画像と音声をロードする

ファイル名: js-game/quest_00944.html

下のソースコードをうつして、草原そうげんとキャラクターの画像がぞうを読み込み、いっしょに表示ひょうじしてください。また、BGMをループ再生しつつ、キャラクターをクリックしたら効果音をならします。

画像がぞうは下のリンクからダウンロードできます。

画像をダウンロード

画像をダウンロード

音声おんせいファイルは下のリンクからダウンロードできます。この素材は「魔王魂」からお借りしています。

フィールドBGMをダウンロード

クリック効果音をダウンロード

ソースコード

class AudioAsset {

  constructor(pool) {
    this.pool = pool;
  }

  play(loop = false) {
    const audio = this.pool.find(audio => audio.ended || audio.currentTime === 0);
    if (audio) {
      audio.loop = loop;
      audio.play();
      return audio;
    }
  }

  playEndless() {
    return this.play(true);
  }

}

class Game {

  constructor() {
    this.assetPromises = [];
    this.assets = {};
  }

  addImage(name, url) {
    const img = new Image();
    img.src = url;
    const promise = new Promise((resolve, reject) => {
      img.addEventListener("load", e => {
        this.assets[name] = img;
        resolve(img);
      });
    });
    this.assetPromises.push(promise);
  }

  addAudio(name, url, num = 1) {
    const pool = [];
    for (let i = 0; i < num; i++) {
      const audio = new Audio(url);
      const promise = new Promise((resolve, reject) => {
        audio.addEventListener("canplaythrough", e => {
          resolve(audio);
        });
      })
      this.assetPromises.push(promise);
      pool.push(audio);
    }
    this.assets[name] = new AudioAsset(pool);
  }

  loadAssets() {
    return Promise.all(this.assetPromises);
  }
}


const game = new Game();
game.addImage("mapchip", "array-map.png");
game.addImage("character", "pipo-charachip022.png");
game.addAudio("bgm", "bgm_maoudamashii_8bit13.mp3");
game.addAudio("click", "se_maoudamashii_onepoint07.mp3", 5);

game.loadAssets().then(() => {

  var canvas = document.getElementById("canvas");
  var context = canvas.getContext("2d");
  for (var y = 0; y < 10; y++) {
    for (var x = 0; x < 10; x++) {
      context.drawImage(game.assets.mapchip, 40, 0, 40, 40, x * 32, y * 32, 32, 32);
    }
  }
  context.drawImage(game.assets.character, 0, 0, 32, 32, 96, 96, 32, 32);

  game.assets.bgm.playEndless();

  canvas.addEventListener("click", (e) => {
    const rect = e.target.getBoundingClientRect();
    const x = e.clientX - rect.left - 1;
    const y = e.clientY - rect.top - 1;
    if (x >= 96 && x < 96 + 32 && y >= 96 && y < 96 + 32) {
      game.assets.click.play();
    }
  });

});

解説

GameクラスのaddImageで画像を、addAudioで音声を読み込みます。音声を最後まで再生するのに十分なデータがロードされると、canplaythroughイベントがおきます。

ロードしたファイルはすべて配列assetsに入れられます。ファイルのロードがすべて完了すると、thenで囲まれた関数が実行され、画像の表示、BGMのループ再生、クリックイベントに反応して効果音を鳴らすイベントリスナーの準備がされます。