// UI Module - Handle screens and user interactions class UIManager { constructor() { this.screens = { room: document.getElementById('room-screen'), lobby: document.getElementById('lobby-screen'), game: document.getElementById('game-screen'), gameover: document.getElementById('gameover-screen') }; this.inputs = { playerName: document.getElementById('player-name') }; this.buttons = { join: document.getElementById('join-btn'), ready: document.getElementById('ready-btn'), leave: document.getElementById('leave-btn'), backToLobby: document.getElementById('back-to-lobby') }; this.displays = { gameRoomName: document.getElementById('game-room-name'), playerList: document.getElementById('player-list'), spectatorList: document.getElementById('spectator-list'), battleGrid: document.getElementById('battle-grid'), gameStatus: document.getElementById('game-status'), winnerDisplay: document.getElementById('winner-display'), finalScores: document.getElementById('final-scores') }; this.bindEvents(); } bindEvents() { this.buttons.join.addEventListener('click', () => this.handleJoin()); this.buttons.ready.addEventListener('click', () => this.handleReady()); this.buttons.leave.addEventListener('click', () => this.handleLeave()); this.buttons.backToLobby.addEventListener('click', () => this.handleBackToLobby()); // Allow Enter key to submit forms this.inputs.playerName.addEventListener('keypress', (e) => { if (e.key === 'Enter') this.handleJoin(); }); } showScreen(screenName) { Object.values(this.screens).forEach(screen => screen.classList.remove('active')); this.screens[screenName].classList.add('active'); } handleJoin() { const playerName = this.inputs.playerName.value.trim(); if (!playerName) { this.showMessage('Please enter your name'); return; } network.joinLobby(playerName); } handleReady() { if (this.buttons.ready.textContent === 'READY') { network.ready(); this.buttons.ready.textContent = 'UNREADY'; this.buttons.ready.disabled = false; } else { network.unready(); this.buttons.ready.textContent = 'READY'; this.buttons.ready.disabled = false; } } handleLeave() { network.leaveLobby(); this.showScreen('room'); } handleBackToLobby() { this.hideGameOver(); this.resetLobbyState(); this.buttons.ready.disabled = false; this.showScreen('room'); } resetLobbyState() { // Reset ready button to default state this.buttons.ready.textContent = 'READY'; this.buttons.ready.disabled = false; // Clear player and spectator lists this.displays.playerList.innerHTML = ''; this.displays.spectatorList.innerHTML = ''; // Reset game room name this.displays.gameRoomName.textContent = 'GLOBAL LOBBY'; this.displays.gameRoomName.classList.remove('spectator-mode'); } updatePlayerList(players) { this.displays.playerList.innerHTML = ''; Object.values(players).forEach(player => { const item = document.createElement('div'); item.className = 'player-item'; const statusClass = player.ready ? 'ready' : ''; item.innerHTML = ` ${this.escapeHtml(player.name)} ${player.ready ? 'READY' : 'WAITING'} `; this.displays.playerList.appendChild(item); }); } updateSpectatorList(spectators) { this.displays.spectatorList.innerHTML = ''; Object.values(spectators).forEach(spectator => { const item = document.createElement('div'); item.className = 'player-item spectator'; item.innerHTML = ` ${this.escapeHtml(spectator.name)} WATCHING `; this.displays.spectatorList.appendChild(item); }); } showSpectatorMode() { // Update UI to indicate spectator mode this.displays.gameRoomName.textContent = 'SPECTATOR MODE - Waiting for next game'; this.displays.gameRoomName.classList.add('spectator-mode'); } hideSpectatorMode() { this.displays.gameRoomName.classList.remove('spectator-mode'); } showMessage(message) { this.displays.gameStatus.textContent = message; setTimeout(() => { this.displays.gameStatus.textContent = ''; }, 3000); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } showGameOver(winner, scores) { this.displays.winnerDisplay.textContent = winner ? `Winner: ${winner}!` : 'Game Over!'; this.displays.winnerDisplay.style.color = winner ? '#0f0' : '#fff'; this.displays.finalScores.innerHTML = ''; Object.entries(scores).forEach(([name, data], index) => { const item = document.createElement('div'); item.className = 'score-item' + (index === 0 ? ' winner' : ''); if (data.eliminated) item.classList.add('eliminated'); item.innerHTML = ` ${this.escapeHtml(name)} Score: ${data.score} Garbage: ${data.garbageReceived} `; this.displays.finalScores.appendChild(item); }); this.screens.gameover.classList.add('active'); } hideGameOver() { this.screens.gameover.classList.remove('active'); } } window.ui = new UIManager();