Files
battle-royal-tetris/public/js/app.js
T
jozamudi 833256d18f Fix lobby: only show players who have joined
Changes:
- Added socket.join(LOBBY_ROOM) when player joins lobby
- Changed io.emit() to io.to(LOBBY_ROOM).emit() for all lobby events
- Players only see lobby events after they click JOIN LOBBY
- Fixed player list to update correctly when players join/ready
- Game now starts properly when all players are ready

Files modified:
- server/index.js: Use Socket.io rooms for lobby scoping
- public/js/app.js: Show lobby screen on player-joined event
- public/js/ui.js: Removed duplicate listener override
2026-03-20 07:30:42 -07:00

176 lines
4.4 KiB
JavaScript

// Main Application - Ties everything together
let localGame = null;
let renderer = null;
let lastTime = 0;
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
// Connect to server
network.connect();
// Initialize renderer
renderer = new TetrisRenderer('battle-grid');
// Setup network listeners
setupNetworkListeners();
// Setup keyboard controls
setupKeyboardControls();
});
function setupNetworkListeners() {
// Player joined lobby
network.setListener('player-joined', (player) => {
ui.updatePlayerList(network.getAllPlayers());
// Show lobby screen if we're on the login screen
if (ui.screens.room.classList.contains('active')) {
ui.showScreen('lobby');
}
});
// Player left lobby
network.setListener('player-left', (playerId) => {
ui.updatePlayerList(network.getAllPlayers());
});
// Game started
network.setListener('game-started', (players, states) => {
ui.showScreen('game');
ui.displays.gameRoomName.textContent = 'GLOBAL LOBBY';
// Clear old boards
renderer.clearAll();
// Create boards for all players
states.forEach((state) => {
const player = network.getPlayer(state.playerId);
renderer.createPlayerBoard(state.playerId, player.name);
// Initialize local game for current player
if (state.playerId === network.currentPlayerId) {
localGame = new TetrisGame(state.playerId);
localGame.loadState(state);
}
});
// Set up battle grid layout
updateBattleGridLayout(players.length);
// Start game loop
lastTime = performance.now();
requestAnimationFrame(gameLoop);
});
// State update during game
network.setListener('state-update', (states) => {
// Update local game if it's our state
const localState = states.find(s => s.playerId === network.currentPlayerId);
if (localState) {
localGame.loadState(localState);
}
// Check for game over
const allStates = network.getAllGameStates();
const activePlayers = Object.values(allStates).filter(s => !s.eliminated);
if (activePlayers.length <= 1) {
endGame(allStates);
}
});
// Game over
network.setListener('game-over', (data) => {
endGame(data.states);
});
}
function setupKeyboardControls() {
document.addEventListener('keydown', (e) => {
if (ui.screens.game.classList.contains('active') && localGame) {
switch (e.key) {
case 'ArrowLeft':
network.sendMove('left');
e.preventDefault();
break;
case 'ArrowRight':
network.sendMove('right');
e.preventDefault();
break;
case 'ArrowDown':
network.sendDrop();
e.preventDefault();
break;
case 'ArrowUp':
network.sendRotate();
e.preventDefault();
break;
case ' ':
network.sendHardDrop();
e.preventDefault();
break;
}
}
});
}
function updateBattleGridLayout(playerCount) {
ui.displays.battleGrid.classList.remove('grid-2x2', 'grid-2x4');
if (playerCount <= 4) {
ui.displays.battleGrid.classList.add('grid-2x2');
} else {
ui.displays.battleGrid.classList.add('grid-2x4');
}
}
function endGame(states) {
// Find winner
const activePlayers = Object.values(states).filter(s => !s.eliminated);
const eliminatedPlayers = Object.values(states).filter(s => s.eliminated);
let winner = null;
let scores = {};
if (activePlayers.length === 1) {
const winnerState = activePlayers[0];
const winnerPlayer = network.getPlayer(winnerState.playerId);
winner = winnerPlayer.name;
}
// Build scores list
Object.values(states).forEach(state => {
const player = network.getPlayer(state.playerId);
if (player) {
scores[player.name] = state.score;
}
});
ui.showGameOver(winner, scores);
}
function gameLoop(currentTime) {
if (!ui.screens.game.classList.contains('active')) {
return;
}
const deltaTime = currentTime - lastTime;
lastTime = currentTime;
// Update local game
if (localGame) {
localGame.update(deltaTime);
}
// Render all players
const allStates = network.getAllGameStates();
Object.values(allStates).forEach(state => {
renderer.renderPlayer(state.playerId, state);
});
// Set active player highlight
renderer.setActivePlayer(network.currentPlayerId);
requestAnimationFrame(gameLoop);
}