Switch repo to English, add i18n with EN/DE language files and first-start language selection

- in-game texts moved to lang/en.lang and lang/de.lang (key = text, placeholders)
- game logic emits message keys + args, translated at display time
- localStorage access via own miniquad JS plugin (www/dc_plugin.js)
- code comments, DESIGN.md, CREDITS.md translated; README.md added

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-02 22:53:03 +01:00
1 parent a101f6ddc4
commit fbf6f223fc
18 files changed
+1072 -362

No files matched your search

+8 -8
View File
@@ -1,6 +1,6 @@
// Sound-Wiedergabe. Die Spiellogik meldet Ereignisse (Sfx), hier werden sie abgespielt.
// Klänge werden später generiert und per `SoundBank::set` (WAV-Bytes) registriert.
// Ohne registrierten Klang bleibt ein Ereignis stumm.
// Sound playback. The game logic reports events (Sfx), they are played here.
// Sounds will be generated later and registered via `SoundBank::set` (WAV bytes).
// Events without a registered sound stay silent.
use crate::game::{Sfx, SfxEvent, SFX_ALL};
use macroquad::audio::{load_sound_from_bytes, play_sound, PlaySoundParams, Sound};
@@ -18,7 +18,7 @@ impl SoundBank {
SoundBank { sounds: vec![None; SFX_ALL.len()], last: vec![-1.0; SFX_ALL.len()], volume: 0.7, muted: false }
}
// Klang für ein Ereignis registrieren (WAV- oder OGG-Bytes)
// register the sound for an event (WAV or OGG bytes)
#[allow(dead_code)]
pub async fn set(&mut self, sfx: Sfx, bytes: &[u8]) -> bool {
match load_sound_from_bytes(bytes).await {
@@ -30,14 +30,14 @@ impl SoundBank {
}
}
// Hier werden später die prozedural erzeugten Klänge registriert.
// procedurally generated sounds will be registered here
pub async fn generate_all(&mut self) {}
pub fn change_volume(&mut self, d: f32) {
self.volume = (self.volume + d).clamp(0.0, 1.0);
}
// Mindestabstand zwischen zwei gleichen Klängen (gegen Klangbrei)
// minimum gap between two identical sounds (avoids a wall of noise)
fn min_gap(sfx: Sfx) -> f64 {
match sfx {
Sfx::Dig | Sfx::GoldDig | Sfx::MeleeHit | Sfx::Shoot | Sfx::GateHit | Sfx::CoreHit => 0.08,
@@ -56,7 +56,7 @@ impl SoundBank {
if now - self.last[i] < Self::min_gap(ev.sfx) {
return;
}
// Lautstärke nach Entfernung zur Bildschirmmitte
// volume by distance to the listener
let mut vol = self.volume;
if let Some((wx, wy)) = ev.pos {
let d = ((wx - listener.x).powi(2) + (wy - listener.y).powi(2)).sqrt();
@@ -71,7 +71,7 @@ impl SoundBank {
}
}
// Hilfsfunktion für die spätere Generierung: Samples (-1..1, mono) -> WAV (16 bit PCM)
// helper for sound generation: samples (-1..1, mono) -> WAV (16 bit PCM)
#[allow(dead_code)]
pub fn wav_from_samples(samples: &[f32], rate: u32) -> Vec<u8> {
let data_len = (samples.len() * 2) as u32;