import * as Phaser from 'phaser'; import { GAME_HEIGHT, GAME_WIDTH, COLORS } from '../config.js'; import { connectSocket, getSocket } from '../services/socket.js'; import { Button } from '../ui/Button.js'; import { Modal } from '../ui/Modal.js'; export default class LobbyScene extends Phaser.Scene { constructor() { super('Lobby'); } init(data) { this.game = data.game; } create() { const cx = GAME_WIDTH / 2; this.add.text(cx, 100, `${this.game.name} — Lobby`, { fontFamily: 'Righteous', fontSize: '52px', color: COLORS.textHex, }).setOrigin(0.5); this.listText = this.add.text(cx, 220, 'Connecting…', { fontFamily: '"Julius Sans One"', fontSize: '24px', color: COLORS.mutedHex, }).setOrigin(0.5); this.roomContainer = this.add.container(0, 280); new Button(this, cx - 220, GAME_HEIGHT - 120, 'Create table', () => this.createRoom()); new Button(this, cx + 220, GAME_HEIGHT - 120, 'Back', () => this.exitLobby(), { variant: 'ghost' }); const socket = connectSocket(); socket.on('connect_error', (err) => this.listText.setText(`Socket error: ${err.message}`)); socket.on('connect', () => { this.listText.setText('No tables yet. Create one to start.'); socket.emit('lobby:subscribe', this.game.slug); }); socket.on('lobby:update', (rooms) => this.renderRooms(rooms)); } exitLobby() { const socket = getSocket(); socket.emit('lobby:unsubscribe', this.game.slug); this.scene.start('GameMenu'); } renderRooms(rooms) { this.roomContainer.removeAll(true); if (!rooms.length) { this.listText.setText('No tables yet. Create one to start.'); return; } this.listText.setText(`${rooms.length} table(s) open`); const cx = GAME_WIDTH / 2; rooms.forEach((room, i) => { const y = i * 90; const bg = this.add.rectangle(cx, y, 1200, 70, COLORS.panel).setStrokeStyle(1, COLORS.accent); const label = this.add.text(cx - 580, y, `${room.name} · ${room.players.length}/${room.maxPlayers}`, { fontSize: '24px', color: COLORS.textHex, }).setOrigin(0, 0.5); const joinBtn = new Button(this, cx + 500, y, 'Join', () => this.joinRoom(room.id), { width: 140, height: 52, fontSize: 22 }); this.roomContainer.add([bg, label, joinBtn]); }); } createRoom() { const socket = getSocket(); socket.emit('room:create', { gameSlug: this.game.slug }, (resp) => { if (!resp?.ok) { new Modal(this, resp?.error ?? 'Could not create table.', { color: COLORS.dangerHex, autoCloseMs: 2400 }); return; } this.scene.start('GameRoom', { game: this.game, room: resp.room }); }); } joinRoom(roomId) { const socket = getSocket(); socket.emit('room:join', { roomId }, (resp) => { if (!resp?.ok) { new Modal(this, resp?.error ?? 'Could not join.', { color: COLORS.dangerHex, autoCloseMs: 2400 }); return; } this.scene.start('GameRoom', { game: this.game, room: resp.room }); }); } }