зеркало из
https://github.com/kodackx/disinformation-quest.git
synced 2025-10-29 12:46:03 +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 [open, setOpen] = useState(true);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [step, setStep] = useState(0);
|
const [step, setStep] = useState(0);
|
||||||
|
const [showButton, setShowButton] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
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 = [
|
const messages = [
|
||||||
@ -33,15 +39,28 @@ export const EndGameDialog = ({ onContinue, startFade }: EndGameDialogProps) =>
|
|||||||
t('endGame.message3')
|
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) {
|
if (step < messages.length - 1) {
|
||||||
setStep(step + 1);
|
// Advance to next message
|
||||||
} else {
|
timer = setTimeout(() => setStep(step + 1), messageDelay);
|
||||||
setOpen(false);
|
} else if (step === messages.length - 1 && !showButton) {
|
||||||
setTimeout(() => {
|
// Show button after last message
|
||||||
onContinue();
|
timer = setTimeout(() => setShowButton(true), showButtonDelay);
|
||||||
}, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [step, messages.length, showButton]);
|
||||||
|
|
||||||
|
const handleViewReport = () => {
|
||||||
|
setOpen(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
onContinue();
|
||||||
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -84,14 +103,23 @@ export const EndGameDialog = ({ onContinue, startFade }: EndGameDialogProps) =>
|
|||||||
</div>
|
</div>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="flex justify-center mt-8">
|
<AnimatePresence>
|
||||||
<Button
|
{showButton && (
|
||||||
onClick={handleNext}
|
<motion.div
|
||||||
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"
|
initial={{ opacity: 0, y: 20 }}
|
||||||
>
|
animate={{ opacity: 1, y: 0 }}
|
||||||
{step < messages.length - 1 ? t('buttons.continue') : t('buttons.viewReport')}
|
transition={{ duration: 0.5 }}
|
||||||
</Button>
|
className="flex justify-center mt-8"
|
||||||
</div>
|
>
|
||||||
|
<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 -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>
|
<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
|
// Start the fade to black and fade out loading overlay
|
||||||
setShowFinalFade(true);
|
setShowFinalFade(true);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
// Stop the background music here, before the fade completes
|
||||||
|
stopBackgroundMusic();
|
||||||
// Wait for fade to complete
|
// Wait for fade to complete
|
||||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
await new Promise(resolve => setTimeout(resolve, 1500));
|
||||||
|
// Set game complete after fade is done
|
||||||
setGameComplete(true);
|
setGameComplete(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,11 +36,13 @@ export function startBackgroundMusic() {
|
|||||||
|
|
||||||
export function stopBackgroundMusic() {
|
export function stopBackgroundMusic() {
|
||||||
if (backgroundMusic) {
|
if (backgroundMusic) {
|
||||||
|
console.log('Stopping background music');
|
||||||
backgroundMusic.pause();
|
backgroundMusic.pause();
|
||||||
backgroundMusic.currentTime = 0;
|
backgroundMusic.currentTime = 0;
|
||||||
backgroundMusic = null;
|
backgroundMusic = null;
|
||||||
}
|
}
|
||||||
if (finalMusic) {
|
if (finalMusic) {
|
||||||
|
console.log('Stopping final music');
|
||||||
finalMusic.pause();
|
finalMusic.pause();
|
||||||
finalMusic.currentTime = 0;
|
finalMusic.currentTime = 0;
|
||||||
finalMusic = null;
|
finalMusic = null;
|
||||||
@ -48,31 +50,64 @@ export function stopBackgroundMusic() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function switchToFinalMusic() {
|
export function switchToFinalMusic() {
|
||||||
// Fade out current background music
|
// If there's already final music playing, don't start it again
|
||||||
if (backgroundMusic) {
|
if (finalMusic) {
|
||||||
const fadeOut = setInterval(() => {
|
console.log('Final music already playing, skipping...');
|
||||||
if (backgroundMusic && backgroundMusic.volume > 0.05) {
|
return;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// Create or get a cached audio element
|
||||||
|
|||||||
Загрузка…
x
Ссылка в новой задаче
Block a user