mirror of
https://github.com/MaciejkaG/statki.git
synced 2024-11-30 00:52:56 +01:00
Major changes
- Fully working ship placement system - Validating ship positions works too - Client side ship data display works as well - Changes to field colors to dark grey instead of light. This improves comfort of use and ensures proper contrast on lower quality displays and ease of use.
This commit is contained in:
parent
7c4801db2d
commit
bb17dc47ba
10
index.js
10
index.js
@ -238,11 +238,15 @@ io.on('connection', async (socket) => {
|
||||
if (playerGame.data.state === 'preparation') {
|
||||
const playerShips = await GInfo.getPlayerShips(socket);
|
||||
let canPlace = bships.validateShipPosition(playerShips, type, posX, posY, rot);
|
||||
let shipAvailable = bships.getShipsAvailable(playerShips)[type] > 0;
|
||||
|
||||
if (canPlace) {
|
||||
console.log("placed");
|
||||
if (!canPlace) {
|
||||
socket.emit("toast", "Nie możesz postawić tak statku");
|
||||
} else if (!shipAvailable) {
|
||||
socket.emit("toast", "Nie masz już statków tego typu");
|
||||
} else {
|
||||
socket.emit("toast", "Nie możesz postawić tak statku")
|
||||
await GInfo.placeShip(socket, { type: type, posX: posX, posY: posY, rot: rot });
|
||||
socket.emit("placed ship", { type: type, posX: posY, posY: posX, rot: rot });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -2,9 +2,9 @@
|
||||
font-size: 20px;
|
||||
|
||||
|
||||
--field: rgb(201, 201, 201);
|
||||
--mark-line: rgb(136, 136, 136);
|
||||
--mark-spot: rgb(68, 68, 68);
|
||||
--field: rgb(36, 36, 36);
|
||||
--mark-line: rgb(59, 59, 59);
|
||||
--mark-spot: rgb(90, 90, 90);
|
||||
--mark-ship-valid: hsl(120, 100%, 80%);
|
||||
--mark-ship-invalid: hsl(0, 100%, 80%);
|
||||
--ship-valid: hsl(120, 70%, 55%);
|
||||
@ -77,13 +77,19 @@ h1,h2,h3,h4,h5,h6 {
|
||||
background: var(--ship-valid);
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s;
|
||||
transform: scale(0);
|
||||
transition: opacity 0.25s, transform 0.25s 0.05s;
|
||||
}
|
||||
|
||||
#secondaryBoard .field .shipField {
|
||||
background: var(--ship-invalid);
|
||||
}
|
||||
|
||||
.field .shipField.active {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.field svg {
|
||||
opacity: 0;
|
||||
width: 100%;
|
||||
|
@ -3,7 +3,7 @@ class Battleships {
|
||||
if (boardSize>0) {
|
||||
this.boardSize = boardSize;
|
||||
} else {
|
||||
throw new Error("Wrong boardSize for the 'Battleships' class");
|
||||
throw new Error("Incorrect boardSize for the 'Battleships' class");
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,9 @@ class Battleships {
|
||||
}
|
||||
|
||||
getField(x, y) {
|
||||
if (0 < x && x <= this.boardSize && 0 < y && y <= this.boardSize) {
|
||||
if (0 <= x && x < this.boardSize && 0 <= y && y < this.boardSize) {
|
||||
x++;
|
||||
y++;
|
||||
return $(`#board .row:nth-child(${y}) .field:nth-child(${x})`);
|
||||
} else {
|
||||
throw new RangeError("getField position out of range.");
|
||||
@ -30,20 +32,50 @@ class Battleships {
|
||||
}
|
||||
|
||||
getRow(row) {
|
||||
row = parseInt(row)+1
|
||||
row++;
|
||||
if (row<=this.boardSize) {
|
||||
return $(`#board .row:nth-child(${row}) .field`);
|
||||
} else {
|
||||
throw new RangeError("getColumn position out of range.");
|
||||
throw new RangeError("getRow position out of range.");
|
||||
}
|
||||
}
|
||||
|
||||
getColumn(column) {
|
||||
column = parseInt(column)+1
|
||||
column++;
|
||||
if (column<=this.boardSize) {
|
||||
return $(`#board .row .field:nth-child(${column})`);
|
||||
} else {
|
||||
throw new RangeError("getColumn position out of range.");
|
||||
}
|
||||
}
|
||||
|
||||
placeShip(data) {
|
||||
let fields = [];
|
||||
switch (data.rot) {
|
||||
case 0:
|
||||
for (let i = 0; i <= data.type; i++) {
|
||||
fields.push([data.posX + i, data.posY]);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (let i = 0; i <= data.type; i++) {
|
||||
fields.push([data.posX, data.posY + i]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (let i = 0; i <= data.type; i++) {
|
||||
fields.push([data.posX - i, data.posY]);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (let i = 0; i <= data.type; i++) {
|
||||
fields.push([data.posX, data.posY - i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
fields.forEach(field => {
|
||||
this.getField(field[0], field[1]).children(".shipField").addClass("active");
|
||||
});
|
||||
}
|
||||
}
|
@ -10,10 +10,13 @@ var previousRow = $(":not(*)");
|
||||
var previousColumn = $(":not(*)");
|
||||
var selectedShip = 0;
|
||||
var shipRotation = 0;
|
||||
var shipsLeft = [4, 3, 2, 1];
|
||||
var changedFields = [];
|
||||
|
||||
var hoveredField = null;
|
||||
|
||||
refreshBoardView();
|
||||
|
||||
$("#board .field").hover(function () {
|
||||
hoveredField = this;
|
||||
// Pokaż "miarki"
|
||||
@ -24,17 +27,15 @@ $("#board .field").hover(function () {
|
||||
|
||||
changedFields.push(row, column, $(this));
|
||||
|
||||
row.css("background", "rgb(136, 136, 136)");
|
||||
column.css("background", "rgb(136, 136, 136)");
|
||||
row.css("background", "var(--mark-line)");
|
||||
column.css("background", "var(--mark-line)");
|
||||
|
||||
$(this).css("background", "rgb(68, 68, 68)");
|
||||
$(this).css("background", "var(--mark-spot)");
|
||||
|
||||
previousRow = row;
|
||||
previousColumn = column;
|
||||
|
||||
// Pokaż podgląd statku
|
||||
posX++;
|
||||
posY++;
|
||||
var fields = [];
|
||||
switch (shipRotation) {
|
||||
case 0:
|
||||
@ -61,7 +62,7 @@ $("#board .field").hover(function () {
|
||||
|
||||
var fieldElem;
|
||||
let failed = false;
|
||||
for (let i = 0; i < selectedShip+1; i++) {
|
||||
for (let i = 0; i <= selectedShip; i++) {
|
||||
const field = fields[i];
|
||||
|
||||
try {
|
||||
@ -74,9 +75,9 @@ $("#board .field").hover(function () {
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
fieldElem.css("background", "rgb(255, 163, 163)");
|
||||
fieldElem.css("background", "var(--mark-ship-invalid)");
|
||||
} else {
|
||||
fieldElem.css("background", "rgb(163, 255, 163)");
|
||||
fieldElem.css("background", "var(--mark-ship-valid)");
|
||||
}
|
||||
changedFields.push(fieldElem);
|
||||
}
|
||||
@ -84,7 +85,7 @@ $("#board .field").hover(function () {
|
||||
hoveredField = null;
|
||||
// Wyłącz "miarki" po wyjściu kursora z pola (aby się nie duplikowały w przyszłości)
|
||||
changedFields.forEach(field => {
|
||||
field.css("background", "rgb(201, 201, 201)");
|
||||
field.css("background", "var(--field)");
|
||||
});
|
||||
changedFields.length = 0;
|
||||
});
|
||||
@ -153,9 +154,17 @@ function switchRotation() {
|
||||
}
|
||||
|
||||
function refreshBoardView() {
|
||||
let shipsOfType = shipsLeft[selectedShip];
|
||||
$("#shipsLeft").html(shipsOfType);
|
||||
if (!shipsOfType) {
|
||||
$("#shipsLeft").addClass("danger");
|
||||
} else {
|
||||
$("#shipsLeft").removeClass("danger");
|
||||
}
|
||||
|
||||
if (hoveredField) {
|
||||
changedFields.forEach(field => {
|
||||
field.css("background", "rgb(201, 201, 201)");
|
||||
field.css("background", "var(--field)");
|
||||
});
|
||||
changedFields.length = 0;
|
||||
|
||||
@ -166,16 +175,14 @@ function refreshBoardView() {
|
||||
|
||||
changedFields.push(row, column, $(hoveredField));
|
||||
|
||||
row.css("background", "rgb(136, 136, 136)");
|
||||
column.css("background", "rgb(136, 136, 136)");
|
||||
row.css("background", "var(--mark-line)");
|
||||
column.css("background", "var(--mark-line)");
|
||||
|
||||
$(hoveredField).css("background", "rgb(68, 68, 68)");
|
||||
$(hoveredField).css("background", "var(--mark-field)");
|
||||
|
||||
previousRow = row;
|
||||
previousColumn = column;
|
||||
|
||||
posX++;
|
||||
posY++;
|
||||
var fields = [];
|
||||
switch (shipRotation) {
|
||||
case 0:
|
||||
@ -202,7 +209,7 @@ function refreshBoardView() {
|
||||
|
||||
var fieldElem;
|
||||
let failed = false;
|
||||
for (let i = 0; i < selectedShip + 1; i++) {
|
||||
for (let i = 0; i <= selectedShip; i++) {
|
||||
const field = fields[i];
|
||||
|
||||
try {
|
||||
@ -215,9 +222,9 @@ function refreshBoardView() {
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
fieldElem.css("background", "rgb(255, 163, 163)");
|
||||
fieldElem.css("background", "var(--mark-ship-invalid)");
|
||||
} else {
|
||||
fieldElem.css("background", "rgb(163, 255, 163)");
|
||||
fieldElem.css("background", "var(--mark-ship-valid)");
|
||||
}
|
||||
changedFields.push(fieldElem);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ var timerDestination = null;
|
||||
var gamePhase = 'pregame';
|
||||
|
||||
$('.field').on('click', function () {
|
||||
console.log("Clicked");
|
||||
socket.emit("place ship", selectedShip, $(this).data('pos-x'), $(this).data('pos-y'), shipRotation);
|
||||
});
|
||||
|
||||
@ -21,6 +20,12 @@ socket.on('toast', (msg) => {
|
||||
}).showToast();
|
||||
});
|
||||
|
||||
socket.on("placed ship", (data) => {
|
||||
bsc.placeShip(data);
|
||||
shipsLeft[data.type]--;
|
||||
refreshBoardView();
|
||||
});
|
||||
|
||||
socket.on('connect', () => {
|
||||
$(".cover h1").html("Oczekiwanie na serwer...");
|
||||
});
|
||||
@ -30,9 +35,7 @@ socket.on("players ready", () => {
|
||||
});
|
||||
|
||||
socket.on("player idx", (idx) => {
|
||||
console.log(idx);
|
||||
playerIdx = idx;
|
||||
console.log(playerIdx);
|
||||
});
|
||||
|
||||
socket.on('turn update', (turnData) => {
|
||||
|
@ -35,14 +35,23 @@ export class GameInfo {
|
||||
const gameId = socket.session.activeGame;
|
||||
const key = `game:${gameId}`;
|
||||
|
||||
await this.redis.json.set(key, '$.state', 'action');
|
||||
let nextPlayer = await this.redis.json.get(key, '$.nextPlayer');
|
||||
await this.redis.json.set(key, '.state', 'action');
|
||||
let nextPlayer = await this.redis.json.get(key, '.nextPlayer');
|
||||
nextPlayer = nextPlayer === 0 ? 1 : 0;
|
||||
await this.redis.json.set(key, '$.nextPlayer', nextPlayer);
|
||||
await this.redis.json.set(key, '.nextPlayer', nextPlayer);
|
||||
|
||||
const UTCTs = Math.floor((new Date()).getTime() / 1000 + 30);
|
||||
this.io.to(gameId).emit('turn update', { turn: 0, phase: "action", timerToUTC: UTCTs });
|
||||
}
|
||||
|
||||
async placeShip(socket, shipData) {
|
||||
const gameId = socket.session.activeGame;
|
||||
const key = `game:${gameId}`;
|
||||
const hostId = (await this.redis.json.get(key, {path: '$.hostId'}))[0];
|
||||
|
||||
const playerIdx = socket.request.session.id === hostId ? 0 : 1;
|
||||
let res = await this.redis.json.arrAppend(key, `.boards[${playerIdx}].ships`, shipData);
|
||||
}
|
||||
}
|
||||
|
||||
export function isPlayerInRoom(socket) {
|
||||
@ -95,12 +104,10 @@ export function resetTimers() {
|
||||
// });
|
||||
// }
|
||||
|
||||
export function getShipsAvailable(data, playerIdx) {
|
||||
export function getShipsAvailable(ships) {
|
||||
let shipsLeft = [4, 3, 2, 1];
|
||||
|
||||
const playerShips = shipsLeft.boards[playerIdx].ships;
|
||||
|
||||
playerShips.forEach(ship => {
|
||||
ships.forEach(ship => {
|
||||
shipsLeft[ship.type]--;
|
||||
});
|
||||
|
||||
@ -152,8 +159,6 @@ export function checkHit(data, playerIdx, posX, posY) {
|
||||
}
|
||||
|
||||
export function validateShipPosition(ships, type, posX, posY, rot) {
|
||||
let multips;
|
||||
|
||||
let boardRender = [];
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
@ -165,6 +170,7 @@ export function validateShipPosition(ships, type, posX, posY, rot) {
|
||||
}
|
||||
|
||||
ships.forEach(ship => {
|
||||
|
||||
let multips;
|
||||
|
||||
switch (ship.rot) {
|
||||
@ -181,7 +187,7 @@ export function validateShipPosition(ships, type, posX, posY, rot) {
|
||||
break;
|
||||
|
||||
case 3:
|
||||
multips = [1, 0];
|
||||
multips = [-1, 0];
|
||||
break;
|
||||
}
|
||||
|
||||
@ -190,6 +196,8 @@ export function validateShipPosition(ships, type, posX, posY, rot) {
|
||||
}
|
||||
});
|
||||
|
||||
let multips;
|
||||
|
||||
switch (rot) {
|
||||
case 0:
|
||||
multips = [0, 1];
|
||||
@ -204,18 +212,24 @@ export function validateShipPosition(ships, type, posX, posY, rot) {
|
||||
break;
|
||||
|
||||
case 3:
|
||||
multips = [1, 0];
|
||||
multips = [-1, 0];
|
||||
break;
|
||||
}
|
||||
|
||||
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) {
|
||||
for (let x = 0; x <= type; x++) {
|
||||
if (posY + multips[1] * x > 9 || posY + multips[1] * x < 0 || posX + multips[0] * x > 9 || posX + multips[0] * x < 0) {
|
||||
return false;
|
||||
}
|
||||
if (boardRender[posY + multips[1] * i][posX + multips[0] * i]) {
|
||||
|
||||
let subtrahents = [[0, 0], [0, 1], [1, 0], [0, -1], [-1, 0], [1, 1], [-1, -1], [1, -1], [-1, 1]]; // Usuń cztery ostatnie elementy jeżeli chcesz by statki mogły się stykać rogami
|
||||
for (let y = 0; y < subtrahents.length; y++) {
|
||||
const idxY = posY - subtrahents[y][0] + multips[1] * x;
|
||||
const idxX = posX - subtrahents[y][1] + multips[0] * x;
|
||||
if (!(idxY < 0 || idxY > 9 || idxX < 0 || idxX > 9) && boardRender[idxY][idxX]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
<div class="ownBoardInfo">
|
||||
<h3>Wybrany statek</h3>
|
||||
<h2 class="dynamic" id="selectedShip">Jednomasztowiec</h2>
|
||||
<h3>Dostępne: <span class="dynamic danger">1</span></h3>
|
||||
<h3>Dostępne: <span class="dynamic danger" id="shipsLeft">1</span></h3>
|
||||
</div>
|
||||
<span class="break"></span>
|
||||
<h2>Sterowanie</h2>
|
||||
|
Loading…
Reference in New Issue
Block a user