From 7c4801db2d017b63e0b032a02acb93e479183903 Mon Sep 17 00:00:00 2001 From: MaciejkaG Date: Sun, 3 Mar 2024 01:29:11 +0100 Subject: [PATCH] Major update - Improved frontend - Server-client toasting framework - Huge improvements to server side utils - Working ship placement validation --- index.js | 42 ++++++++++----- public/assets/css/board.css | 14 +++++ public/assets/css/main.css | 12 +++++ public/assets/js/battleships-lib.js | 2 +- public/assets/js/socket-game.js | 20 +++++++- utils/battleships.js | 79 +++++++++++++++++++---------- views/layouts/main.handlebars | 2 + 7 files changed, 130 insertions(+), 41 deletions(-) diff --git a/index.js b/index.js index 9793402..63f9d11 100644 --- a/index.js +++ b/index.js @@ -135,7 +135,7 @@ io.on('connection', async (socket) => { // Teraz utwórz objekt partii w trakcie w bazie Redis const gameId = uuidv4(); redis.json.set(`game:${gameId}`, '$', { - hostId: opp.id, + hostId: opp.request.session.id, state: "pregame", boards: [ { // typ 2 to trójmasztowiec pozycja i obrót na planszy które pola zostały trafione @@ -176,7 +176,6 @@ io.on('connection', async (socket) => { } else { callback({ status: "alreadyInLobby", - gameCode: id, }); } } @@ -212,7 +211,12 @@ io.on('connection', async (socket) => { const members = [...roomMemberIterator(playerGame.id)]; for (let i = 0; i < members.length; i++) { const sid = members[i][0]; - io.to(sid).emit('player idx', i); + const socket = io.sockets.sockets.get(sid); + if (socket.request.session.id === playerGame.data.hostId) { + io.to(sid).emit('player idx', 0); + } else { + io.to(sid).emit('player idx', 1); + } } let UTCTs = Math.floor((new Date()).getTime() / 1000 + 90); @@ -223,21 +227,30 @@ io.on('connection', async (socket) => { AFKEnd(playerGame.id); }); }); + + await redis.json.set(`game:${playerGame.id}`, '$.state', "preparation"); } } socket.on('place ship', async (type, posX, posY, rot) => { const playerGame = await GInfo.getPlayerGameData(socket); - if (playerGame.state === 'preparation') { - + if (playerGame.data.state === 'preparation') { + const playerShips = await GInfo.getPlayerShips(socket); + let canPlace = bships.validateShipPosition(playerShips, type, posX, posY, rot); + + if (canPlace) { + console.log("placed"); + } else { + socket.emit("toast", "Nie możesz postawić tak statku") + } } }); socket.on('shoot', async () => { const playerGame = await GInfo.getPlayerGameData(socket); - if (playerGame.state === 'action') { + if (playerGame.data.state === 'action') { if (bships.checkTurn(playerGame, socket.id)) { } @@ -271,12 +284,15 @@ function resetUserGame(req) { } function endGame(gameId) { - const members = [...roomMemberIterator(gameId)]; - for (let i = 0; i < members.length; i++) { - const sid = members[i][0]; - const socket = io.sockets.sockets.get(sid); - resetUserGame(socket.request); - socket.leave(gameId); + let iterator = roomMemberIterator(gameId); + if (iterator != null) { + const members = [...iterator]; + for (let i = 0; i < members.length; i++) { + const sid = members[i][0]; + const socket = io.sockets.sockets.get(sid); + resetUserGame(socket.request); + socket.leave(gameId); + } } redis.json.del(`game:${gameId}`); @@ -288,5 +304,5 @@ function AFKEnd(gameId) { } function roomMemberIterator(id) { - return io.sockets.adapter.rooms.get(id).entries(); + return io.sockets.adapter.rooms.get(id) == undefined ? null : io.sockets.adapter.rooms.get(id).entries(); } \ No newline at end of file diff --git a/public/assets/css/board.css b/public/assets/css/board.css index 88991a8..53791a3 100644 --- a/public/assets/css/board.css +++ b/public/assets/css/board.css @@ -70,6 +70,20 @@ h1,h2,h3,h4,h5,h6 { transition: background 0.05s; } +.field .shipField { + width: 100%; + aspect-ratio: 1; + border-radius: 20%; + background: var(--ship-valid); + pointer-events: none; + opacity: 0; + transition: opacity 0.15s; +} + +#secondaryBoard .field .shipField { + background: var(--ship-invalid); +} + .field svg { opacity: 0; width: 100%; diff --git a/public/assets/css/main.css b/public/assets/css/main.css index 8070464..9c961c9 100644 --- a/public/assets/css/main.css +++ b/public/assets/css/main.css @@ -13,6 +13,18 @@ to {transform: translateY(0%);} } +.bshipstoast { + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(15px); + color: white; + padding: 0.75rem 1rem; + border-radius: 15px; + border: solid 2px white; + display: flex; + justify-content: center; + align-items: center; +} + .header { text-align: center; } diff --git a/public/assets/js/battleships-lib.js b/public/assets/js/battleships-lib.js index 3b60e46..361dfbe 100644 --- a/public/assets/js/battleships-lib.js +++ b/public/assets/js/battleships-lib.js @@ -12,7 +12,7 @@ class Battleships { for (var i = 0; i < size; i++) { let row = "
"; for (var n = 0; n < size; n++) { - row += `
`; + row += `
`; } row += "
"; board += row; diff --git a/public/assets/js/socket-game.js b/public/assets/js/socket-game.js index e588abe..16de1f8 100644 --- a/public/assets/js/socket-game.js +++ b/public/assets/js/socket-game.js @@ -2,7 +2,24 @@ const socket = io(); var playerIdx; var timerDestination = null; -var gamePhase = "pregame"; +var gamePhase = 'pregame'; + +$('.field').on('click', function () { + console.log("Clicked"); + socket.emit("place ship", selectedShip, $(this).data('pos-x'), $(this).data('pos-y'), shipRotation); +}); + +socket.on('toast', (msg) => { + Toastify({ + text: msg, + duration: 5000, + newWindow: true, + gravity: "bottom", + position: "right", + stopOnFocus: true, + className: "bshipstoast", + }).showToast(); +}); socket.on('connect', () => { $(".cover h1").html("Oczekiwanie na serwer..."); @@ -15,6 +32,7 @@ socket.on("players ready", () => { socket.on("player idx", (idx) => { console.log(idx); playerIdx = idx; + console.log(playerIdx); }); socket.on('turn update', (turnData) => { diff --git a/utils/battleships.js b/utils/battleships.js index f856a13..92b3400 100644 --- a/utils/battleships.js +++ b/utils/battleships.js @@ -1,13 +1,3 @@ -// export class Client { -// constructor(clientId, clientSecret, redirectUri) { -// this.clientId = clientId; -// this.clientSecret = clientSecret; -// this.redirectUri = redirectUri; -// } -// getAccessToken(code) { -// } -// } - export class GameInfo { constructor(redis, io) { this.redis = redis; @@ -24,6 +14,12 @@ export class GameInfo { return game == null ? null : { id: socket.session.activeGame, data: game }; } + async getPlayerShips(socket) { + const game = await this.redis.json.get(`game:${socket.session.activeGame}`); + const idx = socket.request.session.id === game.hostId ? 0 : 1; + return game.boards[idx].ships; + } + async endPrepPhase(socket) { const gameId = socket.session.activeGame; const key = `game:${gameId}`; @@ -152,42 +148,73 @@ export function checkHit(data, playerIdx, posX, posY) { } }); - boardRender.forEach(row => { - let log = ""; - row.forEach(field => { - log += `${field}\t` - }); - console.log(log); - }); - return boardRender[posY][posX]; } -export function validateShipPosition(type, posX, posY, rot) { +export function validateShipPosition(ships, type, posX, posY, rot) { let multips; + let boardRender = []; + + for (let i = 0; i < 10; i++) { + var array = []; + for (let i = 0; i < 10; i++) { + array.push(false); + } + boardRender.push(array); + } + + ships.forEach(ship => { + let multips; + + switch (ship.rot) { + case 0: + multips = [0, 1]; + break; + + case 1: + multips = [1, 0]; + break; + + case 2: + multips = [0, -1]; + break; + + case 3: + multips = [1, 0]; + break; + } + + for (let i = 0; i < ship.type + 1; i++) { + boardRender[ship.posY + multips[1] * i][ship.posX + multips[0] * i] = true; + } + }); + switch (rot) { case 0: - multips = [1, 0]; - break; - - case 1: multips = [0, 1]; break; + case 1: + multips = [1, 0]; + break; + case 2: - multips = [-1, 0]; + multips = [0, -1]; break; case 3: - multips = [0, -1]; + multips = [1, 0]; break; } - for (let i = 0; i < type + 2; i++) { + for (let i = 0; i < type + 1; i++) { if (posY + multips[1] * i > 9 || posY + multips[1] * i < 0 || posX + multips[0] * i > 9 || posX + multips[0] * i < 0) { return false; } + if (boardRender[posY + multips[1] * i][posX + multips[0] * i]) { + return false; + } } return true; diff --git a/views/layouts/main.handlebars b/views/layouts/main.handlebars index 69f05cd..1c33e88 100644 --- a/views/layouts/main.handlebars +++ b/views/layouts/main.handlebars @@ -9,8 +9,10 @@ + + Designed by Maciejka