Skip to content
Snippets Groups Projects
Commit 8f060eb9 authored by jjd358's avatar jjd358
Browse files

Merge branch '8-deadplayers' into 'main'

8 deadplayers

See merge request !13
parents d9279417 1cac60f7
No related branches found
No related tags found
1 merge request!138 deadplayers
......@@ -82,6 +82,16 @@ let gameBoardHandler = (event) => {
);
ctx.fillStyle = "white";
}
if (board[i][j].type === 5) {
ctx.fillStyle = "black";
ctx.fillRect(
j * widthStep + 1,
i * heightStep + 1,
widthStep - 2,
heightStep - 2,
);
ctx.fillStyle = "white";
}
}
}
};
......
......@@ -4,6 +4,15 @@ const cellTypes = {
PLAYERBODY: 2,
FOOD: 3,
BANANA: 4,
BORDER: 5,
};
const COLLISIONTYPES = {
NONE: 0,
FOOD: 1,
BANANA: 2,
BORDER: 3,
SNAKE: 4,
};
function createCell(x, y, type) {
......@@ -50,8 +59,43 @@ function addFood(gameBoard) {
return gameBoard;
}
function checkCollisions(newY, newX, gameBoard) {
// returns a list of players that have collided,
// and a new gameBoard with the players removed
if (
newX < 0 ||
newX >= gameBoard[0].length ||
newY < 0 ||
newY >= gameBoard.length
) {
console.log(`Player has collided with the wall!`);
return COLLISIONTYPES.BORDER;
}
//Handle collision with food
if (gameBoard[newY][newX].type === cellTypes.FOOD) {
console.log(`Player has eaten the food!`);
return COLLISIONTYPES.FOOD;
}
if (gameBoard[newY][newX].type === cellTypes.PLAYERHEAD) {
console.log(`Player has collided with another player!`);
return COLLISIONTYPES.SNAKE;
}
//Handle collision with banana
if (gameBoard[newY][newX].type == cellTypes.BANANA) {
console.log("Slip");
return COLLISIONTYPES.BANANA;
}
//Handle collision with border
if (gameBoard[newY][newX].type == cellTypes.BORDER) {
console.log("Void");
return COLLISIONTYPES.BORDER;
}
return COLLISIONTYPES.NONE;
}
module.exports = {
cellTypes,
COLLISIONTYPES,
createGameBoard: (width, height) => {
let gameBoard = [];
......@@ -102,6 +146,7 @@ module.exports = {
moveOneStep: (gameBoard) => {
//Save board state to allow multiple snake movements
let updatedBoard = gameBoard.map((row) => row.map((cell) => ({ ...cell })));
let deadPlayers = [];
//Loop through board until we find a PLAYERHEAD
for (var i = 0; i < gameBoard.length; i++) {
......@@ -130,47 +175,46 @@ module.exports = {
newX -= 1;
}
// Check for collisions with walls
let collision = checkCollisions(newY, newX, gameBoard);
if (
newX < 0 ||
newX >= gameBoard[0].length ||
newY < 0 ||
newY >= gameBoard.length
collision === COLLISIONTYPES.BANANA ||
collision === COLLISIONTYPES.FOOD
) {
console.log(`Player ${cell.pid} has collided with the wall!`);
// Remove the player from the game (indicating death)
updatedBoard = addFood(updatedBoard);
}
if (collision === COLLISIONTYPES.SNAKE) {
updatedBoard = updatedBoard.map((row) =>
row.map((c) =>
c.pid === cell.pid ? createCell(c.x, c.y, cellTypes.EMPTY) : c,
),
);
deadPlayers.push(cell.pid);
updatedBoard = updatedBoard.map((row) =>
row.map((c) =>
c.pid === gameBoard[newY][newX].pid
? createCell(c.x, c.y, cellTypes.EMPTY)
: c,
),
);
deadPlayers.push(gameBoard[newY][newX].pid);
continue;
}
// Handle collision with food
if (gameBoard[newY][newX].type === cellTypes.FOOD) {
console.log(`Player ${cell.pid} has eaten the food!`);
// Add new body segment at the current head's position
let newBodySegment = createCell(oldX, oldY, cellTypes.PLAYERBODY);
newBodySegment.pid = cell.pid;
newBodySegment.next = cell.next;
cell.next = newBodySegment;
// Place new food somewhere else
updatedBoard = addFood(updatedBoard);
}
// Handle collision with banana
if (gameBoard[newY][newX].type == cellTypes.BANANA) {
console.log("Slip");
updatedBoard[newY][newX] = createCell(newX, newY, cellTypes.EMPTY);
if (collision > COLLISIONTYPES.FOOD) {
updatedBoard = updatedBoard.map((row) =>
row.map((c) =>
c.pid === cell.pid ? createCell(c.x, c.y, cellTypes.EMPTY) : c,
),
);
updatedBoard = addFood(updatedBoard);
deadPlayers.push(cell.pid);
continue;
}
if (collision === COLLISIONTYPES.FOOD) {
let newBodySegment = createCell(oldX, oldY, cellTypes.PLAYERBODY);
newBodySegment.pid = cell.pid;
newBodySegment.next = cell.next;
cell.next = newBodySegment;
}
//Snake head to new position by updating cell object
let newHeadCell = createCell(newX, newY, cellTypes.PLAYERHEAD);
......@@ -207,11 +251,98 @@ module.exports = {
}
}
}
return updatedBoard;
return [updatedBoard, deadPlayers];
},
checkCollisions: (gameBoard) => {
// returns a list of players that have collided,
// and a new gameBoard with the players removed
applyBorders: (gameBoard, borderCounter) => {
let height = gameBoard.length;
let width = gameBoard[0].length;
//console.log(borderCounter);
//Return gameBoard when it is 2x2
if (borderCounter * 2 >= Math.min(height, width) - 2) {
return gameBoard;
}
//Top
for (let x = 0; x < width; x++) {
gameBoard[borderCounter][x].type = cellTypes.BORDER;
gameBoard[borderCounter][x].pid = 0;
gameBoard[borderCounter][x].direction = 0;
gameBoard[borderCounter][x].next = null;
}
//Bottom
for (let x = 0; x < width; x++) {
gameBoard[height - borderCounter - 1][x].type = cellTypes.BORDER;
gameBoard[height - borderCounter - 1][x].pid = 0;
gameBoard[height - borderCounter - 1][x].direction = 0;
gameBoard[height - borderCounter - 1][x].next = null;
}
//Left
for (let y = 0; y < height; y++) {
gameBoard[y][borderCounter].type = cellTypes.BORDER;
gameBoard[y][borderCounter].pid = 0;
gameBoard[y][borderCounter].direction = 0;
gameBoard[y][borderCounter].next = null;
}
//Right
for (let y = 0; y < height; y++) {
gameBoard[y][width - borderCounter - 1].type = cellTypes.BORDER;
gameBoard[y][width - borderCounter - 1].pid = 0;
gameBoard[y][width - borderCounter - 1].direction = 0;
gameBoard[y][width - borderCounter - 1].next = null;
}
return gameBoard;
},
getPlayerView: (gameBoard, pid) => {
let updatedBoard = gameBoard.map((row) => row.map((cell) => ({ ...cell })));
let width = 11;
let height = 11;
let head = null;
for (var i = 0; i < updatedBoard.length; i++) {
for (var j = 0; j < updatedBoard[i].length; j++) {
let cell = updatedBoard[i][j];
if (cell.type === cellTypes.PLAYERHEAD && cell.pid === pid) {
console.log("MY Player head found at: ", cell.x, cell.y);
head = cell;
}
}
}
if (head === null) {
return [];
}
let playerView = [];
for (var i = 0; i <= height; i++) {
let row = [];
for (var j = 0; j <= width; j++) {
let x = head.x + j - Math.floor(width / 2);
let y = head.y + i - Math.floor(height / 2);
if (
x < 0 ||
x >= updatedBoard[0].length ||
y < 0 ||
y >= updatedBoard.length
) {
row.push(cellTypes.BORDER);
} else {
row.push(updatedBoard[y][x]);
}
}
playerView.push(row);
}
return playerView;
},
};
......@@ -2,50 +2,87 @@ const { WebSocketServer } = require("ws");
const gameModule = require("../game/game.js");
class WebSocketModel {
createInterval(game) {
setInterval(() => {
if (!this.games[game].started) return;
let deadPlayers = [];
[this.games[game].gameBoard, deadPlayers] = gameModule.moveOneStep(
this.games[game].gameBoard,
);
if (!this.games[game].elapsedTime) {
this.games[game].elapsedTime = 0;
}
this.games[game].elapsedTime++;
//Every 10 seconds, generate borders
if (this.games[game].elapsedTime % 10 === 0) {
this.games[game].gameBoard = gameModule.applyBorders(
this.games[game].gameBoard,
this.games[game].borderCounter,
);
this.games[game].borderCounter++;
}
if (deadPlayers.length > 0) {
for (let conn of this.games[game].players) {
conn.connection.send(
JSON.stringify({
type: "deadPlayers",
data: deadPlayers,
}),
);
}
}
for (let conn of this.games[game].players) {
let playerView = gameModule.getPlayerView(
this.games[game].gameBoard,
conn.pid,
);
conn.connection.send(
JSON.stringify({
type: "gameBoard",
data: playerView, // YANG: gameModule.getPlayerView()...
}),
);
}
}, 500);
}
constructor() {
this.connections = [];
this.games = {};
this.games["game1"] = {
gameBoard: gameModule.createGameBoard(10, 10),
gameBoard: gameModule.createGameBoard(100, 100),
players: [],
type: "public",
started: false,
readyPlayers: 0,
borderCounter: 0,
};
this.games["game2"] = {
gameBoard: gameModule.createGameBoard(10, 10),
gameBoard: gameModule.createGameBoard(100, 100),
players: [],
type: "public",
started: false,
readyPlayers: 0,
borderCounter: 0,
};
this.games["game3"] = {
gameBoard: gameModule.createGameBoard(10, 10),
gameBoard: gameModule.createGameBoard(100, 100),
players: [],
type: "public",
started: false,
readyPlayers: 0,
borderCounter: 0,
};
this.sockserver = new WebSocketServer({ port: 3001 });
this.onConnection();
for (let game in this.games) {
setInterval(() => {
if (!this.games[game].started) return;
this.games[game].gameBoard = gameModule.moveOneStep(
this.games[game].gameBoard,
);
for (let conn of this.games[game].players) {
conn.send(
JSON.stringify({
type: "gameBoard",
data: this.games[game].gameBoard,
}),
);
}
}, 1000);
this.createInterval(game);
}
}
......@@ -63,12 +100,14 @@ class WebSocketModel {
createGame(gameId, gameType) {
this.games[gameId] = {
gameBoard: gameModule.createGameBoard(10, 10),
gameBoard: gameModule.createGameBoard(100, 100),
players: [],
type: gameType,
started: false,
readyPlayers: 0,
borderCounter: 0,
};
this.createInterval(gameId);
}
moveHandler(connection, message) {
......@@ -113,13 +152,19 @@ class WebSocketModel {
let roomId = connection.protocol;
if (!this.games[roomId].started) {
this.games[roomId].players.push(connection);
this.games[roomId].players.push({
connection,
pid: this.games[roomId].players.length + 1,
});
this.games[roomId].gameBoard = gameModule.addPlayer(
this.games[roomId].gameBoard,
this.games[roomId].players.length,
);
} else {
this.games[roomId].players.push(connection);
this.games[roomId].players.push({
connection,
pid: this.games[roomId].players.length + 1,
});
}
connection.send(
......@@ -130,6 +175,7 @@ class WebSocketModel {
);
connection.on("close", () => {
// Need to fix this
this.games[roomId].players = this.games[roomId].players.filter(
(curr) => curr !== this.games[roomId].players,
);
......@@ -147,7 +193,7 @@ class WebSocketModel {
} else if (message.type === "chat") {
console.log("Received chat: " + message.data);
for (let conn of this.games[roomId].players) {
conn.send(
conn.connection.send(
JSON.stringify({
type: "chat",
data: message.data,
......@@ -158,7 +204,7 @@ class WebSocketModel {
} else if (message.type === "join") {
console.log("Received join: " + message.data);
for (let conn of this.games[roomId].players) {
conn.send(
conn.connection.send(
JSON.stringify({
type: "playerJoined",
data: message.data,
......@@ -172,8 +218,8 @@ class WebSocketModel {
} else if (message.type === "start") {
console.log("Received start: " + message.data);
for (let conn of this.games[roomId].players) {
if (conn !== connection)
conn.send(
if (conn.connection !== connection)
conn.connection.send(
JSON.stringify({ type: "playerReady", data: message.data }),
);
}
......@@ -183,7 +229,7 @@ class WebSocketModel {
this.games[roomId].readyPlayers
) {
for (let conn of this.games[roomId].players) {
conn.send(
conn.connection.send(
JSON.stringify({ type: "start", data: message.data }),
);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment