Major changes

- Fixed a bug causing removing ships to sometimes wrongly assign ship type 0 an additional ship.
- Players now can't switch boards in the preparation phase.
- Added low timer danger animation
- Added enemy board target and crosshair display formatting.
- Minor animation duration tweaks to make stuff look smoother without causing dizziness.
- Ship field X sign (still not used) now formats properly.
This commit is contained in:
MaciejkaG 2024-03-05 21:34:16 +01:00
parent 0663b2c891
commit e221727c95
6 changed files with 74 additions and 36 deletions

View File

@ -67,7 +67,7 @@ h1,h2,h3,h4,h5,h6 {
aspect-ratio: 1; aspect-ratio: 1;
border-radius: 20%; border-radius: 20%;
cursor: pointer; cursor: pointer;
transition: background 0.05s; transition: background 0.1s;
} }
.field .shipField { .field .shipField {
@ -85,7 +85,7 @@ h1,h2,h3,h4,h5,h6 {
background: var(--ship-invalid); background: var(--ship-invalid);
} }
.field .shipField.active { .field.active .shipField {
transform: scale(1); transform: scale(1);
opacity: 1; opacity: 1;
} }
@ -93,11 +93,15 @@ h1,h2,h3,h4,h5,h6 {
.field svg { .field svg {
opacity: 0; opacity: 0;
width: 100%; width: 100%;
height: 100%; aspect-ratio: 1;
transition: opacity 0.3s; display: block;
border-radius: 20%;
transform: scale(0);
transition: opacity 0.25s, transform 0.25s 0.05s;
} }
.field.hit svg { .field.hit svg {
transform: scale(1);
opacity: 1; opacity: 1;
} }
@ -105,14 +109,14 @@ h1,h2,h3,h4,h5,h6 {
color: var(--dynamic); color: var(--dynamic);
} }
.danger {
color: var(--danger);
}
.important { .important {
color: var(--important); color: var(--important);
} }
.danger {
color: var(--danger);
}
.container { .container {
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -156,6 +160,11 @@ h1,h2,h3,h4,h5,h6 {
transition: opacity 0.3s; transition: opacity 0.3s;
} }
#boardSwitch {
opacity: 0.3;
transition: opacity 0.3s;
}
.secondary { .secondary {
transform: translateX(75%) scale(0.3); transform: translateX(75%) scale(0.3);
pointer-events: none; pointer-events: none;
@ -204,3 +213,17 @@ h1,h2,h3,h4,h5,h6 {
transition: opacity 0.5s; transition: opacity 0.5s;
z-index: 999; z-index: 999;
} }
#timer {
transition: color 0.3s;
}
@keyframes timerDanger {
0% { color: var(--important) }
50% { color: var(--danger) }
100% { color: var(--important) }
}
#timer.active {
animation: timerDanger 0.7s infinite ease;
}

View File

@ -12,7 +12,7 @@ class Battleships {
for (var i = 0; i < size; i++) { for (var i = 0; i < size; i++) {
let row = "<div class=\"row\">"; let row = "<div class=\"row\">";
for (var n = 0; n < size; n++) { for (var n = 0; n < size; n++) {
row += `<div class="field" data-pos-x="${n}" data-pos-y="${i}"><div class="shipField"><svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M100 0 L0 100 ' stroke='black' stroke-width='3'/><path d='M0 0 L100 100 ' stroke='black' stroke-width='3'/></svg></div></div>`; row += `<div class="field" data-pos-x="${n}" data-pos-y="${i}"><div class="shipField"><svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M100 0 L0 100 ' stroke='#f33838' stroke-width='10'/><path d='M0 0 L100 100 ' stroke='#f33838' stroke-width='10'/></svg></div></div>`;
} }
row += "</div>"; row += "</div>";
board += row; board += row;
@ -34,7 +34,7 @@ class Battleships {
getRow(row) { getRow(row) {
row++; row++;
if (row<=this.boardSize) { if (row<=this.boardSize) {
return $(`#board .row:nth-child(${row}) .field`); return $(`.board .row:nth-child(${row}) .field`);
} else { } else {
throw new RangeError("getRow position out of range."); throw new RangeError("getRow position out of range.");
} }
@ -43,7 +43,7 @@ class Battleships {
getColumn(column) { getColumn(column) {
column++; column++;
if (column<=this.boardSize) { if (column<=this.boardSize) {
return $(`#board .row .field:nth-child(${column})`); return $(`.board .row .field:nth-child(${column})`);
} else { } else {
throw new RangeError("getColumn position out of range."); throw new RangeError("getColumn position out of range.");
} }
@ -75,7 +75,7 @@ class Battleships {
} }
fields.forEach(field => { fields.forEach(field => {
this.getField(field[0], field[1]).children(".shipField").addClass("active"); this.getField(field[0], field[1]).addClass("active");
}); });
return fields; return fields;

View File

@ -20,7 +20,7 @@ var hoveredField = null;
refreshBoardView(); refreshBoardView();
$("#board .field").hover(function () { $(".board .field").hover(function () {
hoveredField = this; hoveredField = this;
// Pokaż "miarki" // Pokaż "miarki"
let posX = parseInt($(this).data("pos-x")); let posX = parseInt($(this).data("pos-x"));
@ -103,13 +103,19 @@ $("#board .field").hover(function () {
changedFields.length = 0; changedFields.length = 0;
}); });
$("#board .field").on("click", function() { // $(".board .field").on("click", function() {
}); // });
var ownBoardIsActive = true; var ownBoardIsActive = true;
$("#board").removeClass("secondary");
$("#secondaryBoard").addClass("secondary");
$(".ownBoardInfo").css("opacity", 1);
$(".controlsOwnBoard").css("opacity", 1);
function switchBoards() { function switchBoards() {
if (postPrep) {
if (ownBoardIsActive) { // Aktywna jest plansza użytkownika if (ownBoardIsActive) { // Aktywna jest plansza użytkownika
$("#secondaryBoard").removeClass("secondary"); $("#secondaryBoard").removeClass("secondary");
$("#board").addClass("secondary"); $("#board").addClass("secondary");
@ -125,6 +131,8 @@ function switchBoards() {
ownBoardIsActive = !ownBoardIsActive; ownBoardIsActive = !ownBoardIsActive;
} }
}
function switchShips() { function switchShips() {
if (selectedShip===3) { if (selectedShip===3) {
selectedShip = 0; selectedShip = 0;

View File

@ -10,7 +10,7 @@ $('.field').on('click', function () {
}); });
$('.field').on('contextmenu', function () { $('.field').on('contextmenu', function () {
if ($(this).children('.shipField').hasClass('active')) { if ($(this).hasClass('active')) {
let originPos = occupiedFields.find((elem) => elem.pos[0] == $(this).data('pos-x') && elem.pos[1] == $(this).data('pos-y')).origin; let originPos = occupiedFields.find((elem) => elem.pos[0] == $(this).data('pos-x') && elem.pos[1] == $(this).data('pos-y')).origin;
socket.emit("remove ship", originPos[0], originPos[1]); socket.emit("remove ship", originPos[0], originPos[1]);
@ -44,13 +44,12 @@ socket.on("removed ship", (data) => {
}); });
shipFields.forEach(field => { shipFields.forEach(field => {
bsc.getField(field.pos[0], field.pos[1]).children('.shipField').removeClass("active"); bsc.getField(field.pos[0], field.pos[1]).removeClass("active");
}); });
console.log(occupiedFields);
occupiedFields = occupiedFields.filter(n => !shipFields.includes(n)); occupiedFields = occupiedFields.filter(n => !shipFields.includes(n));
console.log(occupiedFields);
console.log(`shipsLeft[${data.type}] = ${shipsLeft[data.type]}`)
shipsLeft[data.type]++; shipsLeft[data.type]++;
refreshBoardView(); refreshBoardView();
}); });
@ -70,10 +69,12 @@ socket.on("player idx", (idx) => {
socket.on('turn update', (turnData) => { socket.on('turn update', (turnData) => {
if (turnData.phase === "preparation") { if (turnData.phase === "preparation") {
$("#whosTurn").html("Faza przygotowań"); $("#whosTurn").html("Faza przygotowań");
$("#boardSwitch").css("opacity", 0.3);
} else { } else {
postPrep = true; postPrep = true;
myTurn = turnData.turn === playerIdx; myTurn = turnData.turn === playerIdx;
turnData.turn === playerIdx ? $("#whosTurn").html("Twoja tura") : $("#whosTurn").html("Tura przeciwnika"); turnData.turn === playerIdx ? $("#whosTurn").html("Twoja tura") : $("#whosTurn").html("Tura przeciwnika");
$("#boardSwitch").css("opacity", 1);
} }
timerDestination = turnData.timerToUTC; timerDestination = turnData.timerToUTC;
@ -94,6 +95,12 @@ setInterval(() => {
const time = Math.abs(UTCNow - timerDestination); const time = Math.abs(UTCNow - timerDestination);
if (time < 10) {
$("#timer").addClass("active");
} else {
$("#timer").removeClass("active");
}
const minutes = Math.floor(time / 60).toLocaleString('pl-PL', {minimumIntegerDigits: 2, useGrouping: false}); const minutes = Math.floor(time / 60).toLocaleString('pl-PL', {minimumIntegerDigits: 2, useGrouping: false});
const seconds = (time - minutes * 60).toLocaleString('pl-PL', { minimumIntegerDigits: 2, useGrouping: false }); const seconds = (time - minutes * 60).toLocaleString('pl-PL', { minimumIntegerDigits: 2, useGrouping: false });

View File

@ -63,7 +63,7 @@ export class GameInfo {
var deletedShip; var deletedShip;
playerShips = playerShips.filter(function (ship) { playerShips = playerShips.filter(function (ship) {
if (!ship.posX != posX || ship.posY != posY) { if (ship.posX == posX && ship.posY == posY) {
deletedShip = ship; deletedShip = ship;
} }

View File

@ -16,14 +16,14 @@
<h2>Sterowanie</h2> <h2>Sterowanie</h2>
<h3 class="controlsOwnBoard"><span class="important">S</span> Zmiana statku</h3> <h3 class="controlsOwnBoard"><span class="important">S</span> Zmiana statku</h3>
<h3 class="controlsOwnBoard"><span class="important">R</span> Obrót statku</h3> <h3 class="controlsOwnBoard"><span class="important">R</span> Obrót statku</h3>
<h3><span class="important">B</span> Zamiana planszy</h3> <h3 id="boardSwitch"><span class="important">B</span> Zamiana planszy</h3>
<span class="break"></span> <span class="break"></span>
<h3><span class="dynamic" id="whosTurn"></span></h3> <h3><span class="dynamic" id="whosTurn"></span></h3>
<h2 class="important" id="timer">∞</h2> <h2 class="important" id="timer">∞</h2>
</div> </div>
<div class="boardContainer"> <div class="boardContainer">
<div id="board" oncontextmenu="return false;"></div> <div class="board" id="board" oncontextmenu="return false;"></div>
<div id="secondaryBoard" class="secondary" oncontextmenu="return false;"></div> <div class="board" id="secondaryBoard" class="secondary" oncontextmenu="return false;"></div>
</div> </div>
<div class="spaceFiller"></div> <div class="spaceFiller"></div>
</div> </div>