8047778a5b
Wellenbasierte Routen-Sim (DefensegeograSimMac) nach dem Tourismustal- Playbook integriert: Sim nach App/sims/tourismusregion (game.html, Sprites 47MB->9.5MB, ohne Eigen-Backend/Editor/Dashboard/Keys), Plattform-Hooks (GGS_LIVE_STATE mit Welle/Budget/Umwelt/Sterne/Lenkung, Submit bei Partie-Ende mit fertigem 0-100-Score, GGS_TUTORIAL, Home- Button, Musik leise). Wrapper + Modul-Detailseite. SQL: module_info (beta, Karte), Glossar-Kernbegriff Besucherlenkung (+Bild, Leichte Sprache) + 12 Zuordnungen, Lehrplan-Mapping auf tourismus- raumentwicklung (primaer) + verkehrserziehung/systemisches-denken. LEHRPLAN.md mit Schwerpunkt Besucherlenkung & Mobilitaet. Lehrer- Backend: Benchmark (Sim-Score direkt), Live-Cockpit-Spalten, needsHelp, Highlights. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
80 lines
2.5 KiB
JavaScript
80 lines
2.5 KiB
JavaScript
// Hintergrundmusik-Player: 15 Titel aus assets/music/ (neu betitelt),
|
|
// gesteuert über das Panel rechts oben (⏮ ⏯ ⏭, Lautstärke, Titel-Auswahl).
|
|
// Läuft über ein einzelnes Audio-Element (Streaming statt Volldecodierung);
|
|
// die saisonale Ambience (audio.js) pausiert, solange Musik spielt.
|
|
|
|
import { audio } from './audio.js';
|
|
|
|
export const TRACKS = [
|
|
{ file: 'pistenglueck.mp3', title: 'Pistenglück' },
|
|
{ file: 'alpenkindheit.mp3', title: 'Als ich klein war in den Bergen' },
|
|
{ file: 'alpenkindheit-abend.mp3', title: 'Alpenkindheit (Abendversion)' },
|
|
{ file: 'auf-skiern.mp3', title: 'Auf Skiern durchs Tal' },
|
|
{ file: 'bergrock.mp3', title: 'Bergrock' },
|
|
{ file: 'gletscherklang.mp3', title: 'Gletscherklang' },
|
|
{ file: 'winterpromenade.mp3', title: 'Winterpromenade' },
|
|
{ file: 'almgluehen.mp3', title: 'Almglühen' },
|
|
{ file: 'seeblick.mp3', title: 'Seeblick im Schnee' },
|
|
{ file: 'talnebel.mp3', title: 'Talnebel' },
|
|
{ file: 'schneegestoeber.mp3', title: 'Schneegestöber' },
|
|
{ file: 'bergfrieden.mp3', title: 'Bergfrieden' },
|
|
{ file: 'kaminabend.mp3', title: 'Kaminabend' },
|
|
{ file: 'erste-flocken.mp3', title: 'Erste Flocken' },
|
|
{ file: 'frostfunken.mp3', title: 'Frostfunken (Jingle)' },
|
|
];
|
|
|
|
export const music = {
|
|
el: null,
|
|
idx: 0,
|
|
playing: false,
|
|
onChange: null, // UI-Callback (Titel/Status aktualisieren)
|
|
|
|
_ensure() {
|
|
if (this.el) return;
|
|
this.el = new Audio();
|
|
this.el.volume = 0.28;
|
|
this.el.addEventListener('ended', () => this.next());
|
|
this.el.addEventListener('error', () => {
|
|
// Datei fehlt/kaputt → einfach weiter zum nächsten Titel
|
|
if (this.playing) this.next();
|
|
});
|
|
},
|
|
|
|
play(i = this.idx) {
|
|
this._ensure();
|
|
this.idx = ((i % TRACKS.length) + TRACKS.length) % TRACKS.length;
|
|
this.el.src = `assets/music/${TRACKS[this.idx].file}`;
|
|
this.el.play().catch(() => { this.playing = false; this.onChange?.(); });
|
|
this.playing = true;
|
|
audio._stopAmbience?.(); // Vogelgezwitscher pausiert, solange Musik läuft
|
|
this.onChange?.();
|
|
},
|
|
|
|
pause() {
|
|
this.el?.pause();
|
|
this.playing = false;
|
|
if (audio.musicOn) audio.startMusic(); // Ambience wieder aufnehmen
|
|
this.onChange?.();
|
|
},
|
|
|
|
toggle() {
|
|
if (this.playing) this.pause();
|
|
else this.play();
|
|
},
|
|
|
|
next() { this.play(this.idx + 1); },
|
|
prev() { this.play(this.idx - 1); },
|
|
|
|
setMuted(m) {
|
|
this._ensure();
|
|
this.el.muted = m;
|
|
},
|
|
|
|
setVolume(v) {
|
|
this._ensure();
|
|
this.el.volume = Math.max(0, Math.min(1, v));
|
|
},
|
|
|
|
current() { return TRACKS[this.idx]; },
|
|
};
|