88 lines
3.0 KiB
JavaScript
88 lines
3.0 KiB
JavaScript
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 });
|
|
});
|
|
}
|
|
}
|