9.6 KiB
スペースゲーム構築プロジェクト その 6: 終了と再起動
レッスン前の小テスト
ゲーム内での表現方法や 終了条件 の表現方法は様々です。なぜゲームが終了したのかは、ゲームを作る側のあなた次第です。ここでは、あなたが今まで作ってきた宇宙ゲームの話をしていると仮定して、いくつかの理由を挙げてみましょう。
N
隻の敵の宇宙船を撃破しました: それはあなたがレベルを完了するために N 隻の敵の宇宙船を破壊する必要があることを別のレベルにゲームを分割する場合はかなり一般的です- あなたの船が破壊されました: 自分の船が破壊されるとゲームに負けるゲームは間違いなくあります。もう一つの一般的なアプローチは、ライフの概念を持っているということです。あなたの宇宙船が破壊されるたびに、それはライフを差し引きます。すべてのライフが失われると、ゲームを失うことになります
N
ポイントを集めました: もう一つの一般的な終了条件は、ポイントを集めることです。どのようにポイントを獲得するかはあなた次第ですが、敵の宇宙船を破壊したり、破壊された時にドロップするアイテムを集めたりと、様々な活動にポイントを割り当てるのが一般的です- レベルをクリアしました: これには、
X
隻の敵の宇宙船を破壊したり、Y
ポイントを集めたり、特定のアイテムを集めたりするなど、いくつかの条件が含まれている場合があります
再起動
人々があなたのゲームを楽しめば、彼らはそれを再プレイしたいと思う可能性が高いです。何らかの理由でゲームが終了したら、再起動するための代替手段を提供すべきです。
✅ どのような条件でゲームが終了したか、そしてどのように再起動を促されるかを少し考えてみてください。
何を構築するか
これらのルールをゲームに追加していくことになります。
- ゲームの勝利。全ての敵の宇宙船を撃破したらゲームの勝利です。さらに、何らかの勝利メッセージを表示します
- 再起動すること。全てのライフが失われたり、ゲームに勝利したら、ゲームを再起動する方法を提供する必要があります。覚えておいてください! ゲームを再初期化する必要があり、以前のゲームの状態をクリアする必要があります
推奨される手順
あなたのために作成されたファイルを 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;
と独立して宣言します。
コードの追加
-
終了条件を追跡します。敵の数を追跡したり、ヒーローの宇宙船が破壊されたかどうかを追跡するコードを追加します
function isHeroDead() { return hero.life <= 0; } function isEnemiesDead() { const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead); return enemies.length === 0; }
-
メッセージハンドラにロジックを追加します。これらの条件を処理するために
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); });
-
新しいメッセージタイプを追加します。これらのメッセージを定数オブジェクトに追加します
GAME_END_LOSS: "GAME_END_LOSS", GAME_END_WIN: "GAME_END_WIN",
-
選択したボタンの押下でゲームを再起動する再起動コードを追加します
Enter
キーの押下を待ち受けます。この押下を待ち受けるために、ウィンドウの eventListener を編集します
else if(evt.key === "Enter") { eventEmitter.emit(Messages.KEY_EVENT_ENTER); }
-
再起動メッセージを追加します。このメッセージをメッセージ定数に追加します
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
-
ゲームルールの実装 以下のゲームルールを実装します
-
プレイヤーの勝利条件。敵の宇宙船を全て撃破した場合、勝利のメッセージを表示します
- まず、関数
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); }
- 関数
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) }
- まず、関数
-
再起動ロジック。すべてのライフが失われたとき、またはプレイヤーが勝ったときに、ゲームを再起動できることを表示します。さらに、リスタートキーが押されるとゲームを再起動します (どのキーをリスタートにマッピングするかはあなたが決めることができます)
- 関数
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); } }
- 関数
-
initGame()
でゲームをリセットするためにeventEmitter
の呼び出しを追加しますeventEmitter.on(Messages.KEY_EVENT_ENTER, () => { resetGame(); });
-
EventEmitter に
clear()
関数を追加しますclear() { this.listeners = {}; }
-
👽 💥 🚀 おめでとうございます、隊長! あなたのゲームは完成しました! よくできました! 🚀 💥 👽
🚀 チャレンジ
音を追加しましょう!レーザーが当たった時や、ヒーローが死んだ時、勝った時など、ゲームを盛り上げるために音を追加することはできますか? JavaScript を使ってサウンドを再生する方法については、こちらの sandbox をご覧ください。
レッスン後の小テスト
復習と自己学習
あなたの課題は新鮮なサンプルゲームを作成することです。だから、どんなゲームを作れそうかを確認するために、そこにある面白いゲームのいくつかを探索してください。