Skip to content
Snippets Groups Projects
Commit 8edaa9cc authored by Jake Dreher's avatar Jake Dreher
Browse files

5 - Create basic rooms. Only handles public rooms created on startup. Private rooms tbd

parent 0205056f
No related branches found
No related tags found
1 merge request!9Resolve "Define Object for Cell"
......@@ -2,12 +2,6 @@ const express = require("express");
const { WebSocketServer } = require("ws");
const gameModule = require("./src/game/game.js");
const webserver = express()
.use((_, res) => res.sendFile("/index.html", { root: `${__dirname}/public` }))
.listen(3000, () => console.log(`Listening on ${3000}`));
const sockserver = new WebSocketServer({ port: 3001 });
// Maintain a list of connections
// This will eventually map connections to lobby or game instances
let connections = [];
......@@ -16,10 +10,51 @@ let games = {};
// TO BE REWRITTEN
games["game1"] = {
gameBoard: gameModule.createGameBoard(100, 100),
gameBoard: gameModule.createGameBoard(10, 10),
players: [],
};
games["game2"] = {
gameBoard: gameModule.createGameBoard(10, 10),
players: [],
};
games["game3"] = {
gameBoard: gameModule.createGameBoard(10, 10),
players: [],
};
let webserver = express();
webserver.use(express.json());
webserver.get("/", (_, res) => {
res.sendFile("index.html", { root: `${__dirname}/public` });
});
webserver.get("/public_games", (_, res) => {
let ids = Object.keys(games);
res.json({ ids: ids });
});
webserver.get("/join_game/:gameId", (req, res) => {
let { gameId } = req.params;
if (!games.hasOwnProperty(gameId)) {
return res.status(404).send();
}
console.log("Sending room", gameId);
// could also use server-side rendering to create the HTML
// that way, we could embed the room code
// and existing chat messages in the generated HTML
// but the client can also get the roomId from the URL
// and use Ajax to request the messages on load
res.sendFile("public/game.html", { root: __dirname });
});
webserver.listen(3000, () => console.log("Web server started."));
const sockserver = new WebSocketServer({ port: 3001 });
let gameBoard = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0],
......@@ -74,13 +109,24 @@ let moveHandler = (connection, message) => {
sockserver.on("connection", (connection) => {
console.log("New client connected!");
connections.push(connection);
console.log(connection.protocol);
let roomId = connection.protocol;
games[roomId].players.push(connection);
games[roomId].gameBoard = gameModule.addPlayer(
games[roomId].gameBoard,
games[roomId].players.length,
);
connection.send(
JSON.stringify({ type: "newUser", data: connections.length }),
JSON.stringify({ type: "newUser", data: games[roomId].players.length }),
);
connection.on("close", () => {
connections = connections.filter((curr) => curr !== connection);
games[roomId].players = games[roomId].players.filter(
(curr) => curr !== games[roomId].players,
);
console.log("Client has disconnected!");
});
......@@ -90,15 +136,10 @@ sockserver.on("connection", (connection) => {
// All messages are expected to have a type
if (message.type === "move") {
console.log("Received move: " + message.data);
moveHandler(connection, message);
for (let conn of connections) {
conn.send(JSON.stringify({ type: "gameBoard", data: gameBoard }));
}
} else if (message.type === "chat") {
console.log("Received chat: " + message.data);
} else if (message.type === "join") {
console.log("Received join: " + message.data);
connection.send(JSON.stringify({ type: "gameBoard", data: gameBoard }));
} else if (message.type === "leave") {
console.log("Received leave: " + message.data);
} else {
......@@ -117,6 +158,18 @@ sockserver.on("connection", (connection) => {
console.log("Server started.");
// Game loop
for (let game in games) {
setInterval(() => {
for (let conn of games[game].players) {
games[game].gameBoard = gameModule.moveOneStep(games[game].gameBoard);
conn.send(
JSON.stringify({ type: "gameBoard", data: games[game].gameBoard }),
);
}
}, 1000);
}
//setInterval(() => {
// console.log('Broadcasting message to clients, connections.length: ', connections.length);
// connections.forEach(connection => {
......
<!doctype html>
<html lang="en">
<head>
<title>WebSocket Example</title>
</head>
<body>
<h1>WebSocket Client</h1>
<input type="text" id="messageInput" placeholder="Type a message..." />
<button id="sendButton">Send</button>
<div id="messages"></div>
<div id="game">
<canvas id="gameCanvas" width="800" height="600"></canvas>
</div>
<script>
let pathParts = window.location.pathname.split("/");
let roomId = pathParts[pathParts.length - 1];
const joinMessage = { type: "join", data: `${roomId}` };
let moveMessage = { type: "move", data: "up", pid: 0 };
const socket = new WebSocket("ws://127.0.0.1:3001", `${roomId}`);
const canvas = document.getElementById("gameCanvas");
const width = canvas.width;
const height = canvas.height;
let gameBoardHandler = (event) => {
let ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = "white";
let board = event.data;
console.log(board);
widthStep = width / board[0].length;
heightStep = height / board.length;
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (board[i][j].type === 0) {
ctx.fillRect(
j * widthStep + 1,
i * heightStep + 1,
widthStep - 2,
heightStep - 2,
);
}
if (board[i][j].type === 1) {
ctx.fillStyle = "red";
ctx.fillRect(
j * widthStep + 1,
i * heightStep + 1,
widthStep - 2,
heightStep - 2,
);
ctx.fillStyle = "white";
}
if (board[i][j].type === 2) {
ctx.fillStyle = "red";
ctx.fillRect(
j * widthStep + 1,
i * heightStep + 1,
widthStep - 2,
heightStep - 2,
);
ctx.fillStyle = "white";
}
if (board[i][j].type === 3) {
ctx.fillStyle = "blue";
ctx.fillRect(
j * widthStep + 1,
i * heightStep + 1,
widthStep - 2,
heightStep - 2,
);
ctx.fillStyle = "white";
}
}
}
};
let newUserHandler = (event) => {
moveMessage.pid = event.data;
};
socket.addEventListener("open", () => {
console.log("Connected to server");
socket.send(JSON.stringify(joinMessage));
});
socket.addEventListener("message", (event) => {
try {
let msg = JSON.parse(event.data);
if (msg.type === "gameBoard") {
gameBoardHandler(msg);
} else if (msg.type === "newUser") {
newUserHandler(msg);
} else {
const messages = document.getElementById("messages");
const messageElement = document.createElement("div");
messageElement.innerText = event.data;
messages.appendChild(messageElement);
}
} catch {
console.log(event.data);
}
});
document.addEventListener("keydown", (event) => {
if (event.key === "ArrowUp") {
moveMessage.data = "up";
socket.send(JSON.stringify(moveMessage));
}
if (event.key === "ArrowDown") {
moveMessage.data = "down";
socket.send(JSON.stringify(moveMessage));
}
if (event.key === "ArrowLeft") {
moveMessage.data = "left";
socket.send(JSON.stringify(moveMessage));
}
if (event.key === "ArrowRight") {
moveMessage.data = "right";
socket.send(JSON.stringify(moveMessage));
}
});
document.getElementById("sendButton").addEventListener("click", () => {
const messageInput = document.getElementById("messageInput");
const message = messageInput.value;
socket.send(message);
messageInput.value = "";
});
</script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<title>WebSocket Example</title>
<title>GBS</title>
<!-- Bootstrap -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
</head>
<body>
<h1>WebSocket Client</h1>
<input type="text" id="messageInput" placeholder="Type a message..." />
<button id="sendButton">Send</button>
<div id="messages"></div>
<h1>GBS</h1>
<div id="game">
<canvas id="gameCanvas" width="800" height="600"></canvas>
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button
class="btn btn-link"
data-toggle="collapse"
data-target="#collapseOne"
aria-expanded="true"
aria-controls="collapseOne"
>
Public Games
</button>
</h5>
</div>
<script>
const joinMessage = { type: "join", data: "Hello, server" };
const socket = new WebSocket("ws://127.0.0.1:3001");
const canvas = document.getElementById("gameCanvas");
const width = canvas.width;
const height = canvas.height;
let moveMessage = { type: "move", data: "up", pid: 0 };
let gameBoardHandler = (event) => {
let ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = "white";
let board = event.data;
widthStep = width / board[0].length;
heightStep = height / board.length;
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (board[i][j] === 0) {
ctx.fillRect(
j * widthStep + 1,
i * heightStep + 1,
widthStep - 2,
heightStep - 2,
);
}
if (board[i][j] === 1) {
ctx.fillStyle = "red";
ctx.fillRect(
j * widthStep + 1,
i * heightStep + 1,
widthStep - 2,
heightStep - 2,
);
ctx.fillStyle = "white";
}
}
}
};
<div
id="collapseOne"
class="collapse show"
aria-labelledby="headingOne"
data-parent="#accordion"
>
<div class="card-body"></div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingTwo">
<h5 class="mb-0">
<button
class="btn btn-link collapsed"
data-toggle="collapse"
data-target="#collapseTwo"
aria-expanded="false"
aria-controls="collapseTwo"
>
Private Games
</button>
</h5>
</div>
<div
id="collapseTwo"
class="collapse"
aria-labelledby="headingTwo"
data-parent="#accordion"
>
<div class="card-body">Test2</div>
</div>
</div>
</div>
let newUserHandler = (event) => {
moveMessage.pid = event.data;
};
<script>
let publicBody = document
.getElementById("collapseOne")
.getElementsByClassName("card-body")[0];
socket.addEventListener("open", () => {
console.log("Connected to server");
socket.send(JSON.stringify(joinMessage));
});
publicBody.textContent = "Loading...";
socket.addEventListener("message", (event) => {
try {
let msg = JSON.parse(event.data);
if (msg.type === "gameBoard") {
gameBoardHandler(msg);
} else if (msg.type === "newUser") {
newUserHandler(msg);
} else {
const messages = document.getElementById("messages");
const messageElement = document.createElement("div");
messageElement.innerText = event.data;
messages.appendChild(messageElement);
}
} catch {
console.log(event.data);
}
fetch("/public_games")
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
publicBody.textContent = "";
for (let i = 0; i < data.ids.length; i++) {
console.log("----------");
console.log(data.ids[i]);
let button = document.createElement("button");
button.textContent = data.ids[i];
button.className = "btn btn-primary";
button.addEventListener("click", () => {
// will redirect to new chatroom immediately
console.log("Joining game " + data.ids[i]);
window.location = `/join_game/${data.ids[i]}`;
});
document.addEventListener("keydown", (event) => {
if (event.key === "ArrowUp") {
moveMessage.data = "up";
socket.send(JSON.stringify(moveMessage));
}
if (event.key === "ArrowDown") {
moveMessage.data = "down";
socket.send(JSON.stringify(moveMessage));
}
if (event.key === "ArrowLeft") {
moveMessage.data = "left";
socket.send(JSON.stringify(moveMessage));
publicBody.appendChild(button);
}
if (event.key === "ArrowRight") {
moveMessage.data = "right";
socket.send(JSON.stringify(moveMessage));
}
});
document.getElementById("sendButton").addEventListener("click", () => {
const messageInput = document.getElementById("messageInput");
const message = messageInput.value;
socket.send(message);
messageInput.value = "";
});
</script>
</body>
......
......@@ -96,19 +96,27 @@ module.exports = {
let newY = oldY;
//New position based on direction
if (cell.direction === 0) { // Up
if (cell.direction === 0) {
// Up
newY -= 1;
} else if (cell.direction === 1) { // Right
} else if (cell.direction === 1) {
// Right
newX += 1;
} else if (cell.direction === 2) { // Down
} else if (cell.direction === 2) {
// Down
newY += 1;
} else if (cell.direction === 3) { // Left
} else if (cell.direction === 3) {
// Left
newX -= 1;
}
//Continue if within bounds
if (newX >= 0 && newX < gameBoard[0].length && newY >= 0 && newY < gameBoard.length) {
if (
newX >= 0 &&
newX < gameBoard[0].length &&
newY >= 0 &&
newY < gameBoard.length
) {
//Snake head to new position by updating cell object
gameBoard[newY][newX] = {
...cell,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment