Tourismusregion: Komplett-Integration (zweite neue Sim, beta)
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>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
// 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]; },
|
||||
};
|
||||
Reference in New Issue
Block a user