From 2e71ab2ab47b81902f399d71710ef0326d104a4b Mon Sep 17 00:00:00 2001
From: Jake Dreher <jdreherschool@gmail.com>
Date: Wed, 4 Sep 2024 18:02:27 -0400
Subject: [PATCH] Implement rudimentary spectator mode, checking for 10 players
 in lobby

---
 public/game.html             |  5 +++
 public/gameClient.js         |  8 ++++
 src/models/WebSocketModel.js | 73 +++++++++++++++++++++---------------
 3 files changed, 56 insertions(+), 30 deletions(-)

diff --git a/public/game.html b/public/game.html
index c156280..b4df495 100644
--- a/public/game.html
+++ b/public/game.html
@@ -10,6 +10,11 @@
       overflow-y: scroll;
       border: 1px solid black;
     }
+    #game {
+      max-width: fit-content;
+      margin-left: auto;
+      margin-right: auto;
+    }
   </style>
 
   <body>
diff --git a/public/gameClient.js b/public/gameClient.js
index 63805ad..f686b7f 100644
--- a/public/gameClient.js
+++ b/public/gameClient.js
@@ -190,6 +190,14 @@ let gameStart = () => {
   canvas.height = height;
   gameDiv.appendChild(canvas);
 
+  let spectateButton = document.createElement("button");
+  spectateButton.id = "spectateButton";
+  spectateButton.innerText = "Spectate Next Player";
+  spectateButton.addEventListener("click", () => {
+    socket.send(JSON.stringify({ type: "spectate", data: "" }));
+  });
+  gameDiv.appendChild(spectateButton);
+
   document.getElementById("chatInput").disabled = false;
 };
 
diff --git a/src/models/WebSocketModel.js b/src/models/WebSocketModel.js
index d157cc4..3adcfb1 100644
--- a/src/models/WebSocketModel.js
+++ b/src/models/WebSocketModel.js
@@ -27,6 +27,11 @@ class WebSocketModel {
 
       if (deadPlayers.length > 0) {
         for (let conn of this.games[game].players) {
+          for (let deadPlayer of deadPlayers) {
+            if (conn.pid === deadPlayer) {
+              conn.spectating = true;
+            }
+          }
           conn.connection.send(
             JSON.stringify({
               type: "deadPlayers",
@@ -37,14 +42,22 @@ class WebSocketModel {
       }
 
       for (let conn of this.games[game].players) {
-        let playerView = gameModule.getPlayerView(
-          this.games[game].gameBoard,
-          conn.pid,
-        );
+        let playerView = null;
+        if (conn.spectating) {
+          playerView = gameModule.getPlayerView(
+            this.games[game].gameBoard,
+            conn.spectatingPlayer,
+          );
+        } else {
+          playerView = gameModule.getPlayerView(
+            this.games[game].gameBoard,
+            conn.pid,
+          );
+        }
         conn.connection.send(
           JSON.stringify({
             type: "gameBoard",
-            data: playerView, // YANG: gameModule.getPlayerView()...
+            data: playerView,
           }),
         );
       }
@@ -53,30 +66,9 @@ class WebSocketModel {
   constructor() {
     this.connections = [];
     this.games = {};
-    this.games["game1"] = {
-      gameBoard: gameModule.createGameBoard(100, 100),
-      players: [],
-      type: "public",
-      started: false,
-      readyPlayers: 0,
-      borderCounter: 0,
-    };
-    this.games["game2"] = {
-      gameBoard: gameModule.createGameBoard(100, 100),
-      players: [],
-      type: "public",
-      started: false,
-      readyPlayers: 0,
-      borderCounter: 0,
-    };
-    this.games["game3"] = {
-      gameBoard: gameModule.createGameBoard(100, 100),
-      players: [],
-      type: "public",
-      started: false,
-      readyPlayers: 0,
-      borderCounter: 0,
-    };
+    this.createGame("game1", "public");
+    this.createGame("game2", "public");
+    this.createGame("game3", "public");
     this.sockserver = new WebSocketServer({ port: 3001 });
 
     this.onConnection();
@@ -106,6 +98,7 @@ class WebSocketModel {
       started: false,
       readyPlayers: 0,
       borderCounter: 0,
+      numPlayers: 0,
     };
     this.createInterval(gameId);
   }
@@ -151,11 +144,17 @@ class WebSocketModel {
 
       let roomId = connection.protocol;
 
-      if (!this.games[roomId].started) {
+      if (
+        !this.games[roomId].started &&
+        this.games[roomId].players.length < 10
+      ) {
         this.games[roomId].players.push({
           connection,
           pid: this.games[roomId].players.length + 1,
+          spectating: false,
+          spectatingPlayer: 1,
         });
+        this.games[roomId].numPlayers = this.games[roomId].numPlayers + 1;
         this.games[roomId].gameBoard = gameModule.addPlayer(
           this.games[roomId].gameBoard,
           this.games[roomId].players.length,
@@ -164,6 +163,8 @@ class WebSocketModel {
         this.games[roomId].players.push({
           connection,
           pid: this.games[roomId].players.length + 1,
+          spectating: true,
+          spectatingPlayer: 1,
         });
       }
 
@@ -215,6 +216,18 @@ class WebSocketModel {
             }
           } else if (message.type === "leave") {
             console.log("Received leave: " + message.data);
+          } else if (message.type === "spectate") {
+            console.log("Received spectate: " + message.data);
+            for (let conn of this.games[roomId].players) {
+              if (conn.connection === connection) {
+                let player = conn.spectatingPlayer;
+                if (player === this.games[roomId].numPlayers) {
+                  conn.spectatingPlayer = 1;
+                } else {
+                  conn.spectatingPlayer++;
+                }
+              }
+            }
           } else if (message.type === "start") {
             console.log("Received start: " + message.data);
             for (let conn of this.games[roomId].players) {
-- 
GitLab