import { Container, Text } from 'pixi.js';
import type { Scene } from '@rpg/engine';
import type { Game } from '../Game';
import { LocationScene } from './LocationScene';
/**
* Главное меню: название, «новая игра», «продолжить» (если есть сейв).
*/
export class MenuScene implements Scene {
private view = new Container();
constructor(private game: Game) {}
enter(): void {
const title = new Text({
text: 'ПЕПЕЛЬНЫЕ ЛУГА',
style: { fontFamily: 'monospace', fontSize: 24, fill: 0xd8c79a }
});
title.anchor.set(0.5);
title.position.set(240, 70);
this.view.addChild(title);
const subtitle = new Text({
text: 'пепел всё ещё дышит',
style: { fontFamily: 'monospace', fontSize: 8, fill: 0x8a8a9a }
});
subtitle.anchor.set(0.5);
subtitle.position.set(240, 96);
this.view.addChild(subtitle);
this.addMenuItem('Новая игра', 140, () => {
void this.game.scenes.replace(new LocationScene(this.game, null));
});
if (this.game.saves.listSlots().length > 0) {
this.addMenuItem('Продолжить', 160, () => {
const save = this.game.saves.load<SaveData>('autosave');
void this.game.scenes.replace(new LocationScene(this.game, save));
});
}
const hint = new Text({
text: 'клик по тайлу — идти · клик по NPC — говорить\nEsc в игре — меню с сохранением',
style: {
fontFamily: 'monospace',
fontSize: 8,
fill: 0x666677,
align: 'center',
lineHeight: 10
}
});
hint.anchor.set(0.5);
hint.position.set(240, 230);
this.view.addChild(hint);
this.game.renderer.uiRoot.addChild(this.view);
}
private addMenuItem(label: string, y: number, onClick: () => void): void {
const item = new Text({
text: label,
style: { fontFamily: 'monospace', fontSize: 12, fill: 0x9fb7a4 }
});
item.anchor.set(0.5);
item.position.set(240, y);
item.eventMode = 'static';
item.cursor = 'pointer';
item.on('pointerdown', onClick);
item.on('pointerover', () => {
item.style.fill = 0xe8f0e9;
});
item.on('pointerout', () => {
item.style.fill = 0x9fb7a4;
});
this.view.addChild(item);
}
update(_dt: number): void {}
render(): void {}
exit(): void {
this.view.destroy({ children: true });
}
}
/** Формат автосейва. */
export interface SaveData {
pos: { x: number; y: number };
flags: Record<string, boolean>;
}