From 0efadb94480c44eda7cbc65f023507287f9a032b Mon Sep 17 00:00:00 2001 From: David Kotnik Date: Sat, 10 Jan 2026 14:19:59 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A4=F0=9F=93=9D=20ENGLISH=20VOICES=20+?= =?UTF-8?q?=20SUBTITLE=20SYSTEM!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ VOICE FILES UPDATED: - All 21 voice paths changed to English (_en_ versions) - Kai: en-US-GuyNeural - Ana: en-US-JennyNeural - Gronk: en-GB-RyanNeural (Deep UK) ✅ SUBTITLE SYSTEM ADDED: - showSubtitle() function (bottom center, 100px from bottom) - playVoice() now accepts subtitle text - Auto fade in/out (500ms/300ms) - Cyan glow effect - Word wrap support - Depth 950 (below VHS, above Polaroid) ✅ STYLING: - Font: Courier New, 20px - Color: White with black stroke (3px) - Shadow: Cyan glow with blur - Duration: 2.8s (synced with 3s shots) NEXT: Add English subtitle text to all 20 playVoice() calls! --- src/scenes/IntroScene.js | 114 ++++++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 25 deletions(-) diff --git a/src/scenes/IntroScene.js b/src/scenes/IntroScene.js index c2aa00eef..a3e9c7046 100644 --- a/src/scenes/IntroScene.js +++ b/src/scenes/IntroScene.js @@ -47,32 +47,32 @@ class IntroScene extends Phaser.Scene { // 🎵 AMBIENT MUSIC this.loadAudioSafe('noir_ambience', 'assets/audio/ambient/noir_ambience.mp3'); - // 🎤 KAI VOICES (12 total) - this.loadAudioSafe('kai_01', 'assets/audio/voiceover/kai_01_beginning.mp3'); - this.loadAudioSafe('kai_02', 'assets/audio/voiceover/kai_02_father.mp3'); - this.loadAudioSafe('kai_03', 'assets/audio/voiceover/kai_03_whole.mp3'); - this.loadAudioSafe('kai_04', 'assets/audio/voiceover/kai_04_virus.mp3'); - this.loadAudioSafe('kai_05', 'assets/audio/voiceover/kai_05_zombies.mp3'); - this.loadAudioSafe('kai_06', 'assets/audio/voiceover/kai_06_alone.mp3'); - this.loadAudioSafe('kai_07', 'assets/audio/voiceover/kai_07_years.mp3'); - this.loadAudioSafe('kai_08', 'assets/audio/voiceover/kai_08_memory.mp3'); - this.loadAudioSafe('kai_09', 'assets/audio/voiceover/kai_09_fog.mp3'); - this.loadAudioSafe('kai_10', 'assets/audio/voiceover/kai_10_wake.mp3'); - this.loadAudioSafe('kai_11', 'assets/audio/voiceover/kai_11_find.mp3'); - this.loadAudioSafe('kai_12', 'assets/audio/voiceover/kai_12_lifetime.mp3'); + // 🎤 KAI VOICES (12 total - ENGLISH) + this.loadAudioSafe('kai_01', 'assets/audio/voiceover/kai_en_01.mp3'); + this.loadAudioSafe('kai_02', 'assets/audio/voiceover/kai_en_02.mp3'); + this.loadAudioSafe('kai_03', 'assets/audio/voiceover/kai_en_03.mp3'); + this.loadAudioSafe('kai_04', 'assets/audio/voiceover/kai_en_04.mp3'); + this.loadAudioSafe('kai_05', 'assets/audio/voiceover/kai_en_05.mp3'); + this.loadAudioSafe('kai_06', 'assets/audio/voiceover/kai_en_06.mp3'); + this.loadAudioSafe('kai_07', 'assets/audio/voiceover/kai_en_07.mp3'); + this.loadAudioSafe('kai_08', 'assets/audio/voiceover/kai_en_08.mp3'); + this.loadAudioSafe('kai_09', 'assets/audio/voiceover/kai_en_09.mp3'); + this.loadAudioSafe('kai_10', 'assets/audio/voiceover/kai_en_10.mp3'); + this.loadAudioSafe('kai_11', 'assets/audio/voiceover/kai_en_11.mp3'); + this.loadAudioSafe('kai_12', 'assets/audio/voiceover/kai_en_12.mp3'); - // 🎤 ANA VOICES (8 total) - this.loadAudioSafe('ana_01', 'assets/audio/voiceover/ana_01_ride.mp3'); - this.loadAudioSafe('ana_02', 'assets/audio/voiceover/ana_02_immortal.mp3'); - this.loadAudioSafe('ana_03', 'assets/audio/voiceover/ana_03_whole.mp3'); - this.loadAudioSafe('ana_04', 'assets/audio/voiceover/ana_04_changed.mp3'); - this.loadAudioSafe('ana_05', 'assets/audio/voiceover/ana_05_parents.mp3'); - this.loadAudioSafe('ana_06', 'assets/audio/voiceover/ana_06_scream.mp3'); - this.loadAudioSafe('ana_07', 'assets/audio/voiceover/ana_07_truth.mp3'); - this.loadAudioSafe('ana_08', 'assets/audio/voiceover/ana_08_two.mp3'); + // 🎤 ANA VOICES (8 total - ENGLISH) + this.loadAudioSafe('ana_01', 'assets/audio/voiceover/ana_en_01.mp3'); + this.loadAudioSafe('ana_02', 'assets/audio/voiceover/ana_en_02.mp3'); + this.loadAudioSafe('ana_03', 'assets/audio/voiceover/ana_en_03.mp3'); + this.loadAudioSafe('ana_04', 'assets/audio/voiceover/ana_en_04.mp3'); + this.loadAudioSafe('ana_05', 'assets/audio/voiceover/ana_en_05.mp3'); + this.loadAudioSafe('ana_06', 'assets/audio/voiceover/ana_en_06.mp3'); + this.loadAudioSafe('ana_07', 'assets/audio/voiceover/ana_en_07.mp3'); + this.loadAudioSafe('ana_08', 'assets/audio/voiceover/ana_en_08.mp3'); - // 🎤 GRONK VOICE - this.loadAudioSafe('gronk_01', 'assets/audio/voiceover/gronk_01_wake.mp3'); + // 🎤 GRONK VOICE (ENGLISH - Deep UK) + this.loadAudioSafe('gronk_01', 'assets/audio/voiceover/gronk_en_01.mp3'); } loadAudioSafe(key, path) { @@ -216,7 +216,7 @@ class IntroScene extends Phaser.Scene { }); } - playVoice(key) { + playVoice(key, subtitleText) { try { if (this.cache.audio.exists(key)) { if (this.currentVoice) this.currentVoice.stop(); @@ -226,6 +226,70 @@ class IntroScene extends Phaser.Scene { } catch (e) { console.warn(`⚠️ Voice ${key} not available`); } + + // Show subtitle at bottom + if (subtitleText) { + this.showSubtitle(subtitleText, 2800); // 2.8s duration (slightly less than 3s shot) + } + } + + showSubtitle(text, duration = 3000) { + // Remove previous subtitle + if (this.currentText) { + this.currentText.destroy(); + } + + const width = this.cameras.main.width; + const height = this.cameras.main.height; + + // Create subtitle at bottom + this.currentText = this.add.text( + width / 2, + height - 100, // 100px from bottom + text, + { + fontFamily: 'Courier New', + fontSize: '20px', + fill: '#ffffff', + stroke: '#000000', + strokeThickness: 3, + shadow: { + offsetX: 2, + offsetY: 2, + color: '#00ffff', + blur: 8, + stroke: false, + fill: true + }, + align: 'center', + wordWrap: { width: width - 100 } + } + ); + this.currentText.setOrigin(0.5); + this.currentText.setAlpha(0); + this.currentText.setDepth(950); // Below VHS but above Polaroid + + // Fade in + this.tweens.add({ + targets: this.currentText, + alpha: 1, + duration: 500, + ease: 'Power2.easeOut' + }); + + // Fade out before end + this.time.delayedCall(duration - 300, () => { + if (this.currentText) { + this.tweens.add({ + targets: this.currentText, + alpha: 0, + duration: 300, + onComplete: () => { + if (this.currentText) this.currentText.destroy(); + } + }); + } + }); } // ═══════════════════════════════════════════════════════════