diff --git a/public/css/style.css b/public/css/style.css index 223f0ca..56fb028 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -151,21 +151,82 @@ button:active { color: #0f0; } -/* Battle Grid - Responsive Layout */ +/* Battle Grid - Focused Layout */ #battle-grid { - display: grid; - gap: 20px; + position: relative; + width: 100%; + height: 80vh; + display: flex; justify-content: center; + align-items: center; margin-top: 20px; } -#battle-grid.grid-2x2 { - grid-template-columns: repeat(2, 1fr); +/* Main player board - centered and large */ +.player-board.main { + position: relative; + z-index: 10; + transform: scale(1); } -#battle-grid.grid-2x4 { - grid-template-columns: repeat(2, 1fr); - grid-template-rows: repeat(2, 1fr); +/* Spectator boards - smaller and around the edges */ +.player-board.spectator { + position: absolute; + transform: scale(0.5); + opacity: 0.7; +} + +.player-board.eliminated { + opacity: 0.4; +} + +/* Position spectator boards around the main board */ +.player-board.spectator.top-left { + top: 20px; + left: 20px; +} + +.player-board.spectator.top-right { + top: 20px; + right: 20px; +} + +.player-board.spectator.bottom-left { + bottom: 20px; + left: 20px; +} + +.player-board.spectator.bottom-right { + bottom: 20px; + right: 20px; +} + +/* Single player - just show main board */ +#battle-grid.single-player { + justify-content: center; + align-items: center; +} + +/* Two players - main centered, spectator to the right */ +#battle-grid.two-players .spectator { + position: static; + transform: none; + opacity: 1; + margin-left: 30px; +} + +#battle-grid.two-players { + display: flex; + justify-content: center; + align-items: center; + gap: 30px; +} + +/* Three+ players - main centered with spectators around */ +#battle-grid.multi-player { + display: flex; + justify-content: center; + align-items: center; } .player-board { @@ -178,13 +239,18 @@ button:active { position: relative; } -.player-board.active { +.player-board.main { border-color: #0ff; + box-shadow: 0 0 30px rgba(0, 255, 255, 0.3); +} + +.player-board.spectator { + border-color: #444; } .player-board.eliminated { border-color: #f00; - opacity: 0.5; + opacity: 0.4; } .player-board canvas { diff --git a/public/js/app.js b/public/js/app.js index 327f2d8..e8ab217 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -115,12 +115,14 @@ function setupKeyboardControls() { } function updateBattleGridLayout(playerCount) { - ui.displays.battleGrid.classList.remove('grid-2x2', 'grid-2x4'); + ui.displays.battleGrid.classList.remove('single-player', 'two-players', 'multi-player'); - if (playerCount <= 4) { - ui.displays.battleGrid.classList.add('grid-2x2'); + if (playerCount === 1) { + ui.displays.battleGrid.classList.add('single-player'); + } else if (playerCount === 2) { + ui.displays.battleGrid.classList.add('two-players'); } else { - ui.displays.battleGrid.classList.add('grid-2x4'); + ui.displays.battleGrid.classList.add('multi-player'); } } diff --git a/public/js/renderer.js b/public/js/renderer.js index f37ea94..043a0db 100644 --- a/public/js/renderer.js +++ b/public/js/renderer.js @@ -101,8 +101,19 @@ class TetrisRenderer { } } - // Update board state classes + // Update board state classes (preserving main/spectator/position classes) + const wasMain = element.classList.contains('main'); + const wasSpectator = element.classList.contains('spectator'); + const positions = ['top-left', 'top-right', 'bottom-left', 'bottom-right']; + const wasPos = positions.some(p => element.classList.contains(p)); element.classList.remove('active', 'eliminated'); + if (wasMain) element.classList.add('main'); + if (wasSpectator) element.classList.add('spectator'); + if (wasPos) { + positions.forEach(p => { + if (element.classList.contains(p)) element.classList.add(p); + }); + } if (gameState && gameState.eliminated) { element.classList.add('eliminated'); } @@ -212,16 +223,30 @@ class TetrisRenderer { } setActivePlayer(playerId) { - // Remove active class from all boards - this.boards.forEach((boardData) => { - boardData.element.classList.remove('active'); + // Remove main class from all boards + this.boards.forEach((boardData, id) => { + boardData.element.classList.remove('active', 'main'); + boardData.element.classList.remove('spectator', 'top-left', 'top-right', 'bottom-left', 'bottom-right'); }); - // Add to current player - const boardData = this.boards.get(playerId); - if (boardData) { - boardData.element.classList.add('active'); + // Add main class to current player + const mainBoard = this.boards.get(playerId); + if (mainBoard) { + mainBoard.element.classList.add('main'); } + + // Add spectator class to other boards with positions + const positions = ['top-left', 'top-right', 'bottom-left', 'bottom-right']; + let posIndex = 0; + this.boards.forEach((boardData, id) => { + if (id !== playerId) { + boardData.element.classList.add('spectator'); + if (posIndex < positions.length) { + boardData.element.classList.add(positions[posIndex]); + posIndex++; + } + } + }); } triggerShake(playerId) {