fertig-classic-games/public/src/scenes/LobbyScene.js

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 });
});
}
}