зеркало из
https://github.com/kodackx/disinformation-quest.git
synced 2025-10-28 20:34:15 +02:00
tweaked final audio transition
Этот коммит содержится в:
родитель
d39044699d
Коммит
0e80eed2f2
Двоичные данные
public/final-theme.wav
Обычный файл
Двоичные данные
public/final-theme.wav
Обычный файл
Двоичный файл не отображается.
@ -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) =>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="flex justify-center mt-8">
|
||||
<Button
|
||||
onClick={handleNext}
|
||||
className="bg-emerald-950/20 hover:bg-emerald-950/30 text-emerald-400 border border-emerald-500/50 font-semibold py-6 px-8 text-lg"
|
||||
>
|
||||
{step < messages.length - 1 ? t('buttons.continue') : t('buttons.viewReport')}
|
||||
</Button>
|
||||
</div>
|
||||
<AnimatePresence>
|
||||
{showButton && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="flex justify-center mt-8"
|
||||
>
|
||||
<Button
|
||||
onClick={handleViewReport}
|
||||
className="bg-emerald-950/20 hover:bg-emerald-950/30 text-emerald-400 border border-emerald-500/50 font-semibold py-6 px-8 text-lg"
|
||||
>
|
||||
{t('buttons.viewReport')}
|
||||
</Button>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<div className="absolute -z-10 inset-0 overflow-hidden">
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-emerald-950/20 via-black/40 to-black/60 animate-pulse-slow"></div>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Загрузка…
x
Ссылка в новой задаче
Block a user