diff --git a/public/final-theme.wav b/public/final-theme.wav new file mode 100644 index 0000000..4852256 Binary files /dev/null and b/public/final-theme.wav differ diff --git a/public/final-theme.mp3 b/public/final-theme_backup.mp3 similarity index 100% rename from public/final-theme.mp3 rename to public/final-theme_backup.mp3 diff --git a/src/components/game/EndGameDialog.tsx b/src/components/game/EndGameDialog.tsx index 8e5814e..7675570 100644 --- a/src/components/game/EndGameDialog.tsx +++ b/src/components/game/EndGameDialog.tsx @@ -22,9 +22,15 @@ export const EndGameDialog = ({ onContinue, startFade }: EndGameDialogProps) => const [open, setOpen] = useState(true); const { t } = useTranslation(); const [step, setStep] = useState(0); + const [showButton, setShowButton] = useState(false); useEffect(() => { - switchToFinalMusic(); + // Start final music when dialog appears, with a slight delay to match the fade-in + const timer = setTimeout(() => { + switchToFinalMusic(); + }, 800); // Match the dialog's fade-in duration + + return () => clearTimeout(timer); }, []); const messages = [ @@ -33,15 +39,28 @@ export const EndGameDialog = ({ onContinue, startFade }: EndGameDialogProps) => t('endGame.message3') ]; - const handleNext = () => { + useEffect(() => { + const messageDelay = 4000; // 4 seconds per message + const showButtonDelay = 2000; // 1.5 seconds after last message + + let timer: NodeJS.Timeout; + if (step < messages.length - 1) { - setStep(step + 1); - } else { - setOpen(false); - setTimeout(() => { - onContinue(); - }, 500); + // Advance to next message + timer = setTimeout(() => setStep(step + 1), messageDelay); + } else if (step === messages.length - 1 && !showButton) { + // Show button after last message + timer = setTimeout(() => setShowButton(true), showButtonDelay); } + + return () => clearTimeout(timer); + }, [step, messages.length, showButton]); + + const handleViewReport = () => { + setOpen(false); + setTimeout(() => { + onContinue(); + }, 500); }; return ( @@ -84,14 +103,23 @@ export const EndGameDialog = ({ onContinue, startFade }: EndGameDialogProps) => -
- -
+ + {showButton && ( + + + + )} +
diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 34527a1..4ffdda4 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -194,8 +194,11 @@ const Index = () => { // Start the fade to black and fade out loading overlay setShowFinalFade(true); setIsLoading(false); + // Stop the background music here, before the fade completes + stopBackgroundMusic(); // Wait for fade to complete await new Promise(resolve => setTimeout(resolve, 1500)); + // Set game complete after fade is done setGameComplete(true); return; } diff --git a/src/utils/audio.ts b/src/utils/audio.ts index c15bb03..888f2d2 100644 --- a/src/utils/audio.ts +++ b/src/utils/audio.ts @@ -36,11 +36,13 @@ export function startBackgroundMusic() { export function stopBackgroundMusic() { if (backgroundMusic) { + console.log('Stopping background music'); backgroundMusic.pause(); backgroundMusic.currentTime = 0; backgroundMusic = null; } if (finalMusic) { + console.log('Stopping final music'); finalMusic.pause(); finalMusic.currentTime = 0; finalMusic = null; @@ -48,31 +50,64 @@ export function stopBackgroundMusic() { } export function switchToFinalMusic() { - // Fade out current background music - if (backgroundMusic) { - const fadeOut = setInterval(() => { - if (backgroundMusic && backgroundMusic.volume > 0.05) { - backgroundMusic.volume -= 0.05; - } else { - clearInterval(fadeOut); - stopBackgroundMusic(); - // Start final music - finalMusic = new Audio("/final-theme.mp3"); - finalMusic.loop = true; - finalMusic.volume = 0; - finalMusic.muted = isMuted; - finalMusic.play().catch(console.error); - // Fade in final music - const fadeIn = setInterval(() => { - if (finalMusic && finalMusic.volume < 0.3) { - finalMusic.volume += 0.05; - } else { - clearInterval(fadeIn); - } - }, 100); - } - }, 100); + // If there's already final music playing, don't start it again + if (finalMusic) { + console.log('Final music already playing, skipping...'); + return; } + + console.log('Attempting to switch to final music...'); + + // Create and prepare the final music track + finalMusic = new Audio("/final-theme.wav"); + finalMusic.loop = false; + finalMusic.volume = 0; + finalMusic.muted = isMuted; + + // Start playing the final track immediately (it will be silent at first) + finalMusic.play().then(() => { + console.log('Final music started successfully'); + + // If background music is playing, fade it out while fading in the final music + if (backgroundMusic) { + console.log('Fading transition between tracks...'); + const fadeTransition = setInterval(() => { + if (backgroundMusic && backgroundMusic.volume > 0.05) { + backgroundMusic.volume -= 0.05; + } + if (finalMusic && finalMusic.volume < 0.3) { + finalMusic.volume += 0.05; + } + if ((!backgroundMusic || backgroundMusic.volume <= 0.05) && + (!finalMusic || finalMusic.volume >= 0.3)) { + clearInterval(fadeTransition); + stopBackgroundMusic(); // This will clean up the background track + console.log('Fade transition complete'); + } + }, 100); + } else { + // If no background music, just fade in the final track + console.log('Fading in final music...'); + const fadeIn = setInterval(() => { + if (!finalMusic) { + clearInterval(fadeIn); + return; + } + if (finalMusic.volume < 0.3) { + finalMusic.volume += 0.05; + } else { + clearInterval(fadeIn); + console.log('Final music fade in complete'); + } + }, 100); + } + }).catch(error => { + console.error('Failed to start final music:', error); + }); + + finalMusic.addEventListener('ended', () => { + console.log('Final music finished playing'); + }); } // Create or get a cached audio element