slop game oder so
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Einstiegspunkt des Frontends: liest die Server-URLs aus dem HTML, baut die
|
||||
* gemeinsamen Dienste (Einstellungen, Audio, API) und startet Phaser.
|
||||
* @module main
|
||||
*/
|
||||
|
||||
import { GAME } from './config.js';
|
||||
import { ERRORS } from './content/texts.js';
|
||||
import { BootScene } from './scenes/BootScene.js';
|
||||
import { BriefingScene } from './scenes/BriefingScene.js';
|
||||
import { DisclaimerScene } from './scenes/DisclaimerScene.js';
|
||||
import { GameOverScene } from './scenes/GameOverScene.js';
|
||||
import { GameScene } from './scenes/GameScene.js';
|
||||
import { HudScene } from './scenes/HudScene.js';
|
||||
import { ControlsScene, CreditsScene, HighscoresScene } from './scenes/InfoScenes.js';
|
||||
import { MenuScene } from './scenes/MenuScene.js';
|
||||
import { PauseScene } from './scenes/PauseScene.js';
|
||||
import { ApiClient } from './systems/ApiClient.js';
|
||||
import { AudioManager } from './systems/AudioManager.js';
|
||||
import { SafeStorage, Settings } from './systems/Settings.js';
|
||||
|
||||
|
||||
/** @param {string} message */
|
||||
function showBootError(message) {
|
||||
const target = document.getElementById('boot-message');
|
||||
if (target) {
|
||||
target.textContent = message;
|
||||
target.classList.add('boot-message--error');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest die vom Server gerenderten URLs (funktioniert auch unter einer Unter-URL).
|
||||
* @param {HTMLElement} shell
|
||||
*/
|
||||
function readContext(shell) {
|
||||
return {
|
||||
staticBase: shell.dataset.staticBase ?? '/static/',
|
||||
api: {
|
||||
highscores: shell.dataset.apiHighscores ?? '/api/highscores',
|
||||
runs: shell.dataset.apiRuns ?? '/api/runs',
|
||||
},
|
||||
disclaimerUrl: shell.dataset.disclaimerUrl ?? '/disclaimer',
|
||||
};
|
||||
}
|
||||
|
||||
function start() {
|
||||
const shell = document.getElementById('game-shell');
|
||||
if (!shell) return;
|
||||
if (typeof window.Phaser === 'undefined') {
|
||||
showBootError(ERRORS.phaserMissing);
|
||||
return;
|
||||
}
|
||||
|
||||
const context = readContext(shell);
|
||||
const settings = new Settings(SafeStorage.forBrowser());
|
||||
const services = {
|
||||
settings,
|
||||
audio: new AudioManager(settings, { staticBase: context.staticBase }),
|
||||
api: new ApiClient(context.api),
|
||||
};
|
||||
// Klangdateien schon jetzt als Bytes laden; dekodiert wird nach der ersten Interaktion.
|
||||
services.audio.preload();
|
||||
|
||||
const game = new Phaser.Game({
|
||||
type: Phaser.AUTO,
|
||||
parent: 'game',
|
||||
width: GAME.width,
|
||||
height: GAME.height,
|
||||
backgroundColor: GAME.backgroundColor,
|
||||
banner: false,
|
||||
// Rechtsklick soll kein Browser-Kontextmenü über dem Spiel öffnen.
|
||||
disableContextMenu: true,
|
||||
scale: { mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH },
|
||||
physics: { default: 'arcade', arcade: { debug: false } },
|
||||
// Ton übernimmt der eigene AudioManager (Kanäle, Synthesizer, Musik). Ohne diese
|
||||
// Einstellung würde Phaser zusätzlich einen eigenen AudioContext anlegen.
|
||||
audio: { noAudio: true },
|
||||
// Reihenfolge = Zeichenreihenfolge: HUD und Pause liegen über dem Spiel.
|
||||
scene: [
|
||||
BootScene,
|
||||
MenuScene,
|
||||
DisclaimerScene,
|
||||
BriefingScene,
|
||||
GameScene,
|
||||
HudScene,
|
||||
PauseScene,
|
||||
GameOverScene,
|
||||
HighscoresScene,
|
||||
ControlsScene,
|
||||
CreditsScene,
|
||||
],
|
||||
callbacks: {
|
||||
preBoot: (g) => {
|
||||
g.registry.set('context', context);
|
||||
g.registry.set('services', services);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Für End-to-End-Tests und Fehlersuche in der Browser-Konsole.
|
||||
window.gloryDefense = game;
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
showBootError(ERRORS.generic);
|
||||
}
|
||||
Reference in New Issue
Block a user