80 lines
2.7 KiB
JavaScript
80 lines
2.7 KiB
JavaScript
import * as Phaser from 'phaser';
|
|
import { GAME_HEIGHT, GAME_WIDTH, COLORS } from '../config.js';
|
|
import { api } from '../services/api.js';
|
|
import { Button } from '../ui/Button.js';
|
|
import { addFullscreenButton } from '../ui/FullscreenButton.js';
|
|
import { playMenuMusic } from '../ui/MenuMusic.js';
|
|
|
|
export default class GameMenuScene extends Phaser.Scene {
|
|
constructor() { super('GameMenu'); }
|
|
|
|
async create() {
|
|
playMenuMusic();
|
|
const cx = GAME_WIDTH / 2;
|
|
|
|
this.add.image(cx, GAME_HEIGHT / 2, 'bg-menu').setDisplaySize(GAME_WIDTH, GAME_HEIGHT);
|
|
addFullscreenButton(this);
|
|
|
|
const titleText = this.add.text(cx, 120, 'Choose a game', {
|
|
fontFamily: 'Righteous',
|
|
fontSize: '64px',
|
|
color: COLORS.textHex,
|
|
}).setOrigin(0.5).setDepth(1);
|
|
this.add.rectangle(cx, 120, titleText.width + 64, titleText.height + 28, 0x000000, 0.7);
|
|
|
|
const loadingText = this.add.text(cx, 220, 'Loading game list…', {
|
|
fontSize: '24px', color: COLORS.mutedHex,
|
|
}).setOrigin(0.5);
|
|
|
|
let games = [];
|
|
try {
|
|
const res = await api.get('/games');
|
|
games = res.games ?? [];
|
|
} catch (err) {
|
|
loadingText.setText(`Failed to load games: ${err.message}`);
|
|
return;
|
|
}
|
|
loadingText.destroy();
|
|
|
|
const tabletop = games.filter((g) => g.category === 'tabletop');
|
|
const cards = games.filter((g) => g.category === 'cards');
|
|
const casino = games.filter((g) => g.category === 'casino');
|
|
const word = games.filter((g) => g.category === 'word');
|
|
|
|
const hasWord = word.length > 0;
|
|
if (hasWord) {
|
|
this.renderColumn('Tabletop', tabletop, cx - 630, 260);
|
|
this.renderColumn('Cards', cards, cx - 210, 260);
|
|
this.renderColumn('Casino', casino, cx + 210, 260);
|
|
this.renderColumn('Word', word, cx + 630, 260);
|
|
} else {
|
|
this.renderColumn('Tabletop', tabletop, cx - 420, 260);
|
|
this.renderColumn('Cards', cards, cx, 260);
|
|
this.renderColumn('Casino', casino, cx + 420, 260);
|
|
}
|
|
|
|
new Button(this, cx, GAME_HEIGHT - 100, 'Back', () => this.scene.start('Landing'), { variant: 'ghost' });
|
|
}
|
|
|
|
renderColumn(title, games, x, y) {
|
|
const panelTop = y - 44;
|
|
const panelBot = games.length > 0 ? y + 80 + (games.length - 1) * 90 + 56 : y + 56;
|
|
const panelH = panelBot - panelTop;
|
|
this.add.rectangle(x, panelTop + panelH / 2, 420, panelH, 0x000000, 0.7);
|
|
|
|
this.add.text(x, y, title, {
|
|
fontFamily: 'Righteous',
|
|
fontSize: '40px',
|
|
color: COLORS.accentHex,
|
|
}).setOrigin(0.5);
|
|
|
|
games.forEach((game, i) => {
|
|
new Button(this, x, y + 80 + i * 90, game.name, () => this.openGame(game), { width: 360 });
|
|
});
|
|
}
|
|
|
|
openGame(game) {
|
|
this.scene.start('OpponentSelect', { game });
|
|
}
|
|
}
|