Newer
Older
rpg / apps / game / src / main.ts
import { Engine, computeScale, ensurePixelFont, type EngineOptions } from '@rpg/engine';
import { Game } from './Game';
import { BootScene } from './scenes/BootScene';

async function main(): Promise<void> {
    const container = document.getElementById('game')!;

    const options: EngineOptions = {
        virtualWidth: Game.VIRTUAL_W,
        virtualHeight: Game.VIRTUAL_H,
        scale: computeScale(Game.VIRTUAL_W, Game.VIRTUAL_H, window.innerWidth, window.innerHeight),
        background: 0x0b0b12,
        fixedFps: 60,
        parent: container
    };

    const engine = new Engine(options);
    await engine.init();
    engine.input.bindActions({
        advance: ['Space', 'Enter'],
        attack: ['Space'], // вне диалога: тап — удар, удержание — резонанс
        menu: ['Escape'],
        inventory: ['KeyI'],
        debug: ['F3'],
        up: ['KeyW', 'ArrowUp'],
        down: ['KeyS', 'ArrowDown'],
        left: ['KeyA', 'ArrowLeft'],
        right: ['KeyD', 'ArrowRight']
    });
    engine.input.bindGamepad({
        advance: [0], // A
        attack: [2], // X
        menu: [9], // Start
        inventory: [3], // Y
        up: [12],
        down: [13],
        left: [14],
        right: [15]
    });

    // Пиксельный шрифт движка (VT323): до первого текста; фолбэк monospace безопасен.
    void ensurePixelFont(Game.FONT_URL);

    const game = new Game(engine);

    // Аудио разрешено только после жеста пользователя: разблокируем на первом вводе.
    const unlockAudio = (): void => {
        void game.audio.unlock();
        window.removeEventListener('pointerdown', unlockAudio);
        window.removeEventListener('keydown', unlockAudio);
    };
    window.addEventListener('pointerdown', unlockAudio);
    window.addEventListener('keydown', unlockAudio);

    await engine.scenes.push(new BootScene(game));
    await engine.start();
}

void main();