diff --git a/public/sounds/boump.mp3 b/public/sounds/boump.mp3 new file mode 100644 index 0000000..42862b8 Binary files /dev/null and b/public/sounds/boump.mp3 differ diff --git a/public/sounds/first.mp3 b/public/sounds/first.mp3 new file mode 100644 index 0000000..0fcf5e2 Binary files /dev/null and b/public/sounds/first.mp3 differ diff --git a/public/sounds/second.mp3 b/public/sounds/second.mp3 new file mode 100644 index 0000000..59ef123 Binary files /dev/null and b/public/sounds/second.mp3 differ diff --git a/public/sounds/snearRoll.mp3 b/public/sounds/snearRoll.mp3 new file mode 100644 index 0000000..0293b2d Binary files /dev/null and b/public/sounds/snearRoll.mp3 differ diff --git a/public/sounds/three.mp3 b/public/sounds/three.mp3 new file mode 100644 index 0000000..23c47a3 Binary files /dev/null and b/public/sounds/three.mp3 differ diff --git a/socket/src/quizz.config.js b/socket/src/quizz.config.js index 46b7528..5ef76a3 100644 --- a/socket/src/quizz.config.js +++ b/socket/src/quizz.config.js @@ -18,7 +18,7 @@ export const GAME_STATE_INIT = { "Bill Gate", ], solution: 1, - cooldow: 5, + cooldown: 5, time: 15, }, { diff --git a/src/components/game/states/Answers.jsx b/src/components/game/states/Answers.jsx index a90c72d..6fcf1cc 100644 --- a/src/components/game/states/Answers.jsx +++ b/src/components/game/states/Answers.jsx @@ -50,9 +50,17 @@ export default function Answers({ volume: 0.2, }) - const [playMusic, { stop: stopMusic }] = useSound(SFX_ANSWERS_MUSIC, { - volume: 0.2, - }) + const [playMusic, { stop: stopMusic, isPlaying }] = useSound( + SFX_ANSWERS_MUSIC, + { + volume: 0.2, + }, + ) + + const handleAnswer = (answer) => { + socket.emit("player:selectedAnswer", answer) + sfxPop() + } useEffect(() => { if (!responses) { @@ -64,11 +72,19 @@ export default function Answers({ sfxResults() setPercentages(calculatePercentages(responses)) + }, [responses, playMusic, stopMusic]) + useEffect(() => { + if (!isPlaying) { + playMusic() + } + }, [isPlaying]) + + useEffect(() => { return () => { stopMusic() } - }, [responses]) + }, [playMusic, stopMusic]) useEffect(() => { socket.on("game:cooldown", (sec) => { @@ -84,7 +100,7 @@ export default function Answers({ socket.off("game:cooldown") socket.off("game:playerAnswer") } - }, []) + }, [sfxPop]) return (
@@ -141,7 +157,7 @@ export default function Answers({ "opacity-65": responses && correct !== key, })} icon={ANSWERS_ICONS[key]} - onClick={() => socket.emit("player:selectedAnswer", key)} + onClick={() => handleAnswer(key)} > {answer} diff --git a/src/components/game/states/Leaderboard.jsx b/src/components/game/states/Leaderboard.jsx index dbfb926..b87d959 100644 --- a/src/components/game/states/Leaderboard.jsx +++ b/src/components/game/states/Leaderboard.jsx @@ -5,8 +5,11 @@ export default function Leaderboard({ data: { leaderboard } }) { Leaderboard
- {leaderboard.map(({ username, points }) => ( -
+ {leaderboard.map(({ username, points }, key) => ( +
{username} {points}
diff --git a/src/components/game/states/Podium.jsx b/src/components/game/states/Podium.jsx index 6f1d378..34763db 100644 --- a/src/components/game/states/Podium.jsx +++ b/src/components/game/states/Podium.jsx @@ -1,17 +1,60 @@ import Loader from "@/components/Loader" +import { + SFX_PODIUM_FIRST, + SFX_PODIUM_SECOND, + SFX_PODIUM_THREE, + SFX_SNEAR_ROOL, +} from "@/constants" import useScreenSize from "@/hook/useScreenSize" import clsx from "clsx" import { useEffect, useState } from "react" import ReactConfetti from "react-confetti" +import useSound from "use-sound" export default function Podium({ data: { subject, top } }) { const [apparition, setApparition] = useState(0) const { width, height } = useScreenSize() + const [sfxtThree] = useSound(SFX_PODIUM_THREE, { + volume: 0.2, + }) + + const [sfxSecond] = useSound(SFX_PODIUM_SECOND, { + volume: 0.2, + }) + + const [sfxRool, { stop: sfxRoolStop }] = useSound(SFX_SNEAR_ROOL, { + volume: 0.2, + }) + + const [sfxFirst] = useSound(SFX_PODIUM_FIRST, { + volume: 0.2, + }) + + useEffect(() => { + console.log(apparition) + switch (apparition) { + case 4: + sfxRoolStop() + sfxFirst() + break + case 3: + sfxRool() + break + case 2: + sfxSecond() + break + case 1: + sfxtThree() + break + } + }, [apparition, sfxFirst, sfxSecond, sfxtThree, sfxRool]) + useEffect(() => { if (top.length < 3) { setApparition(4) + return } const interval = setInterval(() => { @@ -23,7 +66,7 @@ export default function Podium({ data: { subject, top } }) { }, 2000) return () => clearInterval(interval) - }, []) + }, [apparition]) return ( <> @@ -46,13 +89,13 @@ export default function Podium({ data: { subject, top } }) {
{top[1] && (
= 2 }, + { "!translate-y-0 opacity-100": apparition >= 2 }, )} >

= 3, + "!translate-y-0 opacity-100": apparition >= 3, }, { "md:min-w-64": top.length < 2, @@ -110,7 +153,7 @@ export default function Podium({ data: { subject, top } }) { className={clsx( "z-10 flex h-[40%] w-full translate-y-full flex-col items-center gap-3 opacity-0 transition-all", { - "translate-y-0 opacity-100": apparition >= 1, + "!translate-y-0 opacity-100": apparition >= 1, }, )} > diff --git a/src/components/game/states/Result.jsx b/src/components/game/states/Result.jsx index d3b91fb..1d99bef 100644 --- a/src/components/game/states/Result.jsx +++ b/src/components/game/states/Result.jsx @@ -1,19 +1,27 @@ import CricleCheck from "@/components/icons/CricleCheck" import CricleXmark from "@/components/icons/CricleXmark" +import { SFX_RESULTS_SOUND } from "@/constants" import { usePlayerContext } from "@/context/player" import { useEffect } from "react" +import useSound from "use-sound" export default function Result({ data: { correct, message, points, myPoints, totalPlayer, rank, aheadOfMe }, }) { const { dispatch } = usePlayerContext() + const [sfxResults] = useSound(SFX_RESULTS_SOUND, { + volume: 0.2, + }) + useEffect(() => { dispatch({ type: "UPDATE", payload: { points: myPoints }, }) - }, []) + + sfxResults() + }, [sfxResults]) return (

diff --git a/src/components/game/states/Start.jsx b/src/components/game/states/Start.jsx index 8ee7b81..19fe4df 100644 --- a/src/components/game/states/Start.jsx +++ b/src/components/game/states/Start.jsx @@ -1,18 +1,26 @@ +import { SFX_BOUMP_SOUND } from "@/constants" import { useSocketContext } from "@/context/socket" import clsx from "clsx" import { useEffect, useState } from "react" +import useSound from "use-sound" export default function Start({ data: { time, subject } }) { const { socket } = useSocketContext() const [showTitle, setShowTitle] = useState(true) const [cooldown, setCooldown] = useState(time) + const [sfxBoump] = useSound(SFX_BOUMP_SOUND, { + volume: 0.2, + }) + useEffect(() => { socket.on("game:startCooldown", () => { + sfxBoump() setShowTitle(false) }) socket.on("game:cooldown", (sec) => { + sfxBoump() setCooldown(sec) }) @@ -20,7 +28,7 @@ export default function Start({ data: { time, subject } }) { socket.off("game:startCooldown") socket.off("game:cooldown") } - }, []) + }, [sfxBoump]) return (
diff --git a/src/constants.js b/src/constants.js index 2902474..aa9e9ce 100644 --- a/src/constants.js +++ b/src/constants.js @@ -56,3 +56,8 @@ export const SFX_ANSWERS_MUSIC = "/sounds/answersMusic.mp3" export const SFX_ANSWERS_SOUND = "/sounds/answersSound.mp3" export const SFX_RESULTS_SOUND = "/sounds/results.mp3" export const SFX_SHOW_SOUND = "/sounds/show.mp3" +export const SFX_BOUMP_SOUND = "/sounds/boump.mp3" +export const SFX_PODIUM_THREE = "/sounds/three.mp3" +export const SFX_PODIUM_SECOND = "/sounds/second.mp3" +export const SFX_PODIUM_FIRST = "/sounds/first.mp3" +export const SFX_SNEAR_ROOL = "/sounds/snearRoll.mp3" diff --git a/src/styles/globals.css b/src/styles/globals.css index 6e5cb50..ee0bcf6 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -67,7 +67,7 @@ top: -50%; left: -50%; } - 95% { + 98% { opacity: 1; } 100% {