PixiJSでブラウザゲーム 02シーン切替

PixiJSでブラウザゲーム 01基本編ではPixiJSの基本をメモしました。 今回はゲームシーンを2つ作成し、交互に切り替える方法(とシーンの明るさの調整の方法)のメモです。 サンプルでは、ゲームシーンがフェードアウトしながら切り替わります。

目次:

前提

  • PixiJS v5.2.1

サンプルコード

02-scene-fadeout-switch.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>シーンの切り替え(フェードOUT/IN効果付き)</title>
</head>

<body>
  <div>
    シーンの切り替え(フェードOUT/IN効果付き)
    <select onchange="selectScene(event.currentTarget.value)">
      <option>gameScene1</option>
      <option>gameScene2</option>
    </select>
  </div>
  <div>
    シーンの明るさ調整
    <input type="number" min="0" max="1" step="0.1" onchange="setSceneAlpha(event.currentTarget.value)">
  </div>
  <div id="game"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
  <script>
  // pixiアプリケーションのインスタンスを生成
  const app = new PIXI.Application({
    width: 512,
    height: 512,
    antialiasing: true,
    transparent: false,
    resolution: 1
  });

  const gameScenes = {
    /* "gameScene": <Container> */
    /* "gameScene2": <Container> */
  }; // シーン保存領域

  let currentScene; // 現在表示されているシーン

  // #game要素にpixiApp.view追加
  document.querySelector("#game").appendChild(app.view);

  //load an image and run the `setup` function when it's done
  PIXI.Loader.shared
    .add("chara-1", "https://i.imgur.com/JNGbC6F.png")
    .add("chara-2", "https://i.imgur.com/H9smyaD.png")
    .add("chara-3", "https://i.imgur.com/xT6FStW.png")
    .add("explorer", "https://i.imgur.com/rWus6RK.png")
    .add("cat", "https://i.imgur.com/Fk2JkI5.png")
    .add("dungeon", "https://i.imgur.com/EzpxVBZ.png")
    .load(setup);

  //This `setup` function will run when the image has loaded
  function setup(loader, res) {
    //
    // ゲームシーン1を作成
    //
    const gameScene1 = new PIXI.Container();
    app.stage.addChild(gameScene1);
    gameScenes["gameScene1"] = gameScene1; // NOTE: シーンホルダーに保存

    // ダンジョン作成(ここで画面の大枠サイズを確定)
    const dungeon = new PIXI.Sprite(PIXI.utils.TextureCache["dungeon"]);
    gameScene1.addChild(dungeon);
    // アニメーションを作成してシーンに追加
    const anim1 = createAnim(["chara-1", "chara-2", "chara-3", ]);
    anim1.x = 30;
    anim1.y = gameScene1.height / 2 - anim1.height / 2;
    anim1.vx = 0;
    anim1.vy = 0;
    anim1.play();
    gameScene1.addChild(new PIXI.Text("gameScene1", {
      fill: "#ff0000",
    }));
    gameScene1.addChild(anim1);
    currentScene = gameScene1; // NOTE: 現在のシーン

    //
    // ゲームシーン2を作成
    //
    const gameScene2 = new PIXI.Container();
    app.stage.addChild(gameScene2);
    gameScene2.visible = false;
    // テキスト作成
    const style = new PIXI.TextStyle({
      fontFamily: "Futura",
      fontSize: 32,
      fill: "white",
      padding: 40,
    });
    message = new PIXI.Text("gameScene2", style);
    message.x = 120;
    message.y = app.stage.height / 2 - 32;
    gameScene2.addChild(message);
    // アニメーションを作成してシーンに追加
    const anim2 = createAnim(["chara-1", "chara-2", "chara-3", ]);
    anim2.x = 0;
    anim2.y = gameScene2.height / 2 - anim2.height / 2;
    anim2.vx = 0;
    anim2.vy = 0;
    anim2.play();
    message.addChild(anim2);
    gameScenes.gameScene2 = gameScene2;

  }

  /**
   * アニメーションスプライトオブジェクトを作成
   * @param  {Array<String>} imgs - imageパスの配列
   * @param  {Object} opts - [OPTIONAL] オプション @see PIXI.AnimatedSprite
   * @return {AnimatedSprite}
   */
  function createAnim(imgs, opts) {
    const textureArray = [];
    for (let i = 0; i < imgs.length; i++) {
      let texture = PIXI.Texture.from(imgs[i]);
      textureArray.push(texture);
    };
    const animatedSprite = new PIXI.AnimatedSprite(textureArray);
    animatedSprite.animationSpeed = (opts && opts.animationSpeed) ? opts.animationSpeed : 0.1;
    return animatedSprite;
  }

  /** シーンを切り替え */
  function selectScene(sceneKey) {
    // const sceneKey = e.currentTarget.value;
    fadeOut(currentScene, () => {
      currentScene = gameScenes[sceneKey];
      currentScene.alpha = 1.0;
      currentScene.visible = true;
    });

    function fadeOut(sprite, cb) {
      sprite.alpha = sprite.alpha - 0.1;
      if (sprite.alpha <= 0) {
        sprite.visible = false;
        return cb && cb(null);
      }
      setTimeout(() => {
        fadeOut(sprite, cb);
      }, 100);
    }
  }

  /** シーンの明るさ調整 */
  function setSceneAlpha(alpha) {
    currentScene.alpha = alpha;
  }
  </script>
</body>

</html>

実行

ひとこと

ゲームシーンの切り替えが実現できました。 次回はキャラアイコンの動き(エフェクト)を実現してみたいと思います。

宣伝: PixiJSを使ったブラウザゲーム開発なら田中ソフトウェアラボにご相談ください!

オススメ:Zattoyomiで時事ネタチェックの時間節約!
芽萌丸プログラミング部 @programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。記事は主に @TanakaSoftwareLab が担当。