You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/6-space-game/6-end-condition/translations/README.ja.md

9.6 KiB

スペースゲーム構築プロジェクト その 6: 終了と再起動

レッスン前の小テスト

レッスン前の小テスト

ゲーム内での表現方法や 終了条件 の表現方法は様々です。なぜゲームが終了したのかは、ゲームを作る側のあなた次第です。ここでは、あなたが今まで作ってきた宇宙ゲームの話をしていると仮定して、いくつかの理由を挙げてみましょう。

  • N 隻の敵の宇宙船を撃破しました: それはあなたがレベルを完了するために N 隻の敵の宇宙船を破壊する必要があることを別のレベルにゲームを分割する場合はかなり一般的です
  • あなたの船が破壊されました: 自分の船が破壊されるとゲームに負けるゲームは間違いなくあります。もう一つの一般的なアプローチは、ライフの概念を持っているということです。あなたの宇宙船が破壊されるたびに、それはライフを差し引きます。すべてのライフが失われると、ゲームを失うことになります
  • N ポイントを集めました: もう一つの一般的な終了条件は、ポイントを集めることです。どのようにポイントを獲得するかはあなた次第ですが、敵の宇宙船を破壊したり、破壊された時にドロップするアイテムを集めたりと、様々な活動にポイントを割り当てるのが一般的です
  • レベルをクリアしました: これには、X 隻の敵の宇宙船を破壊したり、Y ポイントを集めたり、特定のアイテムを集めたりするなど、いくつかの条件が含まれている場合があります

再起動

人々があなたのゲームを楽しめば、彼らはそれを再プレイしたいと思う可能性が高いです。何らかの理由でゲームが終了したら、再起動するための代替手段を提供すべきです。

どのような条件でゲームが終了したか、そしてどのように再起動を促されるかを少し考えてみてください。

何を構築するか

これらのルールをゲームに追加していくことになります。

  1. ゲームの勝利。全ての敵の宇宙船を撃破したらゲームの勝利です。さらに、何らかの勝利メッセージを表示します
  2. 再起動すること。全てのライフが失われたり、ゲームに勝利したら、ゲームを再起動する方法を提供する必要があります。覚えておいてください! ゲームを再初期化する必要があり、以前のゲームの状態をクリアする必要があります

推奨される手順

あなたのために作成されたファイルを your-work サブフォルダ内で探します。以下のファイルが含まれているはずです。

-| assets
  -| enemyShip.png
  -| player.png
  -| laserRed.png
  -| life.png
-| index.html
-| app.js
-| package.json

次のように入力して、your_work フォルダからプロジェクトを起動します。

cd your-work
npm start

上記のようにすると、http://localhost:5000 というアドレスに HTTP サーバーが起動します。ブラウザを開いて、そのアドレスを入力してください。ゲームがプレイ可能な状態になっているはずです。

ヒント: Visual Studio Code の警告を避けるためには、window.onload 関数を編集して gameLoopId をそのまま (let を省略して) 呼び出し、ファイルの先頭に gameLoopId を let gameLoopId; と独立して宣言します。

コードの追加

  1. 終了条件を追跡します。敵の数を追跡したり、ヒーローの宇宙船が破壊されたかどうかを追跡するコードを追加します

    function isHeroDead() {
      return hero.life <= 0;
    }
    
    function isEnemiesDead() {
      const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead);
      return enemies.length === 0;
    }
    
  2. メッセージハンドラにロジックを追加します。これらの条件を処理するために eventEmitter を編集します

    eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
        first.dead = true;
        second.dead = true;
        hero.incrementPoints();
    
        if (isEnemiesDead()) {
          eventEmitter.emit(Messages.GAME_END_WIN);
        }
    });
    
    eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => {
        enemy.dead = true;
        hero.decrementLife();
        if (isHeroDead())  {
          eventEmitter.emit(Messages.GAME_END_LOSS);
          return; // 勝利前に敗北
        }
        if (isEnemiesDead()) {
          eventEmitter.emit(Messages.GAME_END_WIN);
        }
    });
    
    eventEmitter.on(Messages.GAME_END_WIN, () => {
        endGame(true);
    });
    
    eventEmitter.on(Messages.GAME_END_LOSS, () => {
      endGame(false);
    });
    
  3. 新しいメッセージタイプを追加します。これらのメッセージを定数オブジェクトに追加します

    GAME_END_LOSS: "GAME_END_LOSS",
    GAME_END_WIN: "GAME_END_WIN",
    
  4. 選択したボタンの押下でゲームを再起動する再起動コードを追加します

    1. Enter キーの押下を待ち受けます。この押下を待ち受けるために、ウィンドウの eventListener を編集します
     else if(evt.key === "Enter") {
        eventEmitter.emit(Messages.KEY_EVENT_ENTER);
      }
    
    1. 再起動メッセージを追加します。このメッセージをメッセージ定数に追加します

      KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
      
  5. ゲームルールの実装 以下のゲームルールを実装します

    1. プレイヤーの勝利条件。敵の宇宙船を全て撃破した場合、勝利のメッセージを表示します

      1. まず、関数 displayMessage() を作成します
      function displayMessage(message, color = "red") {
        ctx.font = "30px Arial";
        ctx.fillStyle = color;
        ctx.textAlign = "center";
        ctx.fillText(message, canvas.width / 2, canvas.height / 2);
      }
      
      1. 関数 endGame() を作成します
      function endGame(win) {
        clearInterval(gameLoopId);
      
        // 塗り終わったことを確認するために遅延を設定します
        setTimeout(() => {
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          ctx.fillStyle = "black";
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          if (win) {
            displayMessage(
              "Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew",
              "green"
            );
          } else {
            displayMessage(
              "You died !!! Press [Enter] to start a new game Captain Pew Pew"
            );
          }
        }, 200)  
      }
      
    2. 再起動ロジック。すべてのライフが失われたとき、またはプレイヤーが勝ったときに、ゲームを再起動できることを表示します。さらに、リスタートキーが押されるとゲームを再起動します (どのキーをリスタートにマッピングするかはあなたが決めることができます)

      1. 関数 resetGame() を作成します
      function resetGame() {
        if (gameLoopId) {
          clearInterval(gameLoopId);
          eventEmitter.clear();
          initGame();
          gameLoopId = setInterval(() => {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = "black";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            drawPoints();
            drawLife();
            updateGameObjects();
            drawGameObjects(ctx);
          }, 100);
        }
      }
      
    3. initGame() でゲームをリセットするために eventEmitter の呼び出しを追加します

      eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
        resetGame();
      });
      
    4. EventEmitter に clear() 関数を追加します

      clear() {
        this.listeners = {};
      }
      

👽 💥 🚀 おめでとうございます、隊長! あなたのゲームは完成しました! よくできました! 🚀 💥 👽


🚀 チャレンジ

音を追加しましょう!レーザーが当たった時や、ヒーローが死んだ時、勝った時など、ゲームを盛り上げるために音を追加することはできますか? JavaScript を使ってサウンドを再生する方法については、こちらの sandbox をご覧ください。

レッスン後の小テスト

レッスン後の小テスト

復習と自己学習

あなたの課題は新鮮なサンプルゲームを作成することです。だから、どんなゲームを作れそうかを確認するために、そこにある面白いゲームのいくつかを探索してください。

課題

サンプルゲームを作る