Update Podium & Sound

This commit is contained in:
Ralex91
2024-02-08 15:39:27 +01:00
parent a5adacfaef
commit 8493987f8e
13 changed files with 100 additions and 17 deletions

BIN
public/sounds/boump.mp3 Normal file

Binary file not shown.

BIN
public/sounds/first.mp3 Normal file

Binary file not shown.

BIN
public/sounds/second.mp3 Normal file

Binary file not shown.

BIN
public/sounds/snearRoll.mp3 Normal file

Binary file not shown.

BIN
public/sounds/three.mp3 Normal file

Binary file not shown.

View File

@@ -18,7 +18,7 @@ export const GAME_STATE_INIT = {
"Bill Gate", "Bill Gate",
], ],
solution: 1, solution: 1,
cooldow: 5, cooldown: 5,
time: 15, time: 15,
}, },
{ {

View File

@@ -50,9 +50,17 @@ export default function Answers({
volume: 0.2, volume: 0.2,
}) })
const [playMusic, { stop: stopMusic }] = useSound(SFX_ANSWERS_MUSIC, { const [playMusic, { stop: stopMusic, isPlaying }] = useSound(
volume: 0.2, SFX_ANSWERS_MUSIC,
}) {
volume: 0.2,
},
)
const handleAnswer = (answer) => {
socket.emit("player:selectedAnswer", answer)
sfxPop()
}
useEffect(() => { useEffect(() => {
if (!responses) { if (!responses) {
@@ -64,11 +72,19 @@ export default function Answers({
sfxResults() sfxResults()
setPercentages(calculatePercentages(responses)) setPercentages(calculatePercentages(responses))
}, [responses, playMusic, stopMusic])
useEffect(() => {
if (!isPlaying) {
playMusic()
}
}, [isPlaying])
useEffect(() => {
return () => { return () => {
stopMusic() stopMusic()
} }
}, [responses]) }, [playMusic, stopMusic])
useEffect(() => { useEffect(() => {
socket.on("game:cooldown", (sec) => { socket.on("game:cooldown", (sec) => {
@@ -84,7 +100,7 @@ export default function Answers({
socket.off("game:cooldown") socket.off("game:cooldown")
socket.off("game:playerAnswer") socket.off("game:playerAnswer")
} }
}, []) }, [sfxPop])
return ( return (
<div className="flex h-full flex-1 flex-col justify-between"> <div className="flex h-full flex-1 flex-col justify-between">
@@ -141,7 +157,7 @@ export default function Answers({
"opacity-65": responses && correct !== key, "opacity-65": responses && correct !== key,
})} })}
icon={ANSWERS_ICONS[key]} icon={ANSWERS_ICONS[key]}
onClick={() => socket.emit("player:selectedAnswer", key)} onClick={() => handleAnswer(key)}
> >
{answer} {answer}
</AnswerButton> </AnswerButton>

View File

@@ -5,8 +5,11 @@ export default function Leaderboard({ data: { leaderboard } }) {
Leaderboard Leaderboard
</h2> </h2>
<div className="flex w-full flex-col gap-2"> <div className="flex w-full flex-col gap-2">
{leaderboard.map(({ username, points }) => ( {leaderboard.map(({ username, points }, key) => (
<div className="flex w-full justify-between rounded-md bg-primary p-3 text-2xl font-bold text-white"> <div
key={key}
className="flex w-full justify-between rounded-md bg-primary p-3 text-2xl font-bold text-white"
>
<span className="drop-shadow-md">{username}</span> <span className="drop-shadow-md">{username}</span>
<span className="drop-shadow-md">{points}</span> <span className="drop-shadow-md">{points}</span>
</div> </div>

View File

@@ -1,17 +1,60 @@
import Loader from "@/components/Loader" 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 useScreenSize from "@/hook/useScreenSize"
import clsx from "clsx" import clsx from "clsx"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import ReactConfetti from "react-confetti" import ReactConfetti from "react-confetti"
import useSound from "use-sound"
export default function Podium({ data: { subject, top } }) { export default function Podium({ data: { subject, top } }) {
const [apparition, setApparition] = useState(0) const [apparition, setApparition] = useState(0)
const { width, height } = useScreenSize() 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(() => { useEffect(() => {
if (top.length < 3) { if (top.length < 3) {
setApparition(4) setApparition(4)
return
} }
const interval = setInterval(() => { const interval = setInterval(() => {
@@ -23,7 +66,7 @@ export default function Podium({ data: { subject, top } }) {
}, 2000) }, 2000)
return () => clearInterval(interval) return () => clearInterval(interval)
}, []) }, [apparition])
return ( return (
<> <>
@@ -46,13 +89,13 @@ export default function Podium({ data: { subject, top } }) {
</h2> </h2>
<div <div
className={`grid w-full max-w-[800px] flex-1 grid-cols-3 items-end justify-center justify-self-end overflow-y-hidden overflow-x-visible`} className={`grid w-full max-w-[800px] flex-1 grid-cols-${top.length} items-end justify-center justify-self-end overflow-y-hidden overflow-x-visible`}
> >
{top[1] && ( {top[1] && (
<div <div
className={clsx( className={clsx(
"z-20 flex h-[50%] w-full translate-y-full flex-col items-center justify-center gap-3 opacity-0 transition-all", "z-20 flex h-[50%] w-full translate-y-full flex-col items-center justify-center gap-3 opacity-0 transition-all",
{ "translate-y-0 opacity-100": apparition >= 2 }, { "!translate-y-0 opacity-100": apparition >= 2 },
)} )}
> >
<p <p
@@ -80,7 +123,7 @@ export default function Podium({ data: { subject, top } }) {
className={clsx( className={clsx(
"z-30 flex h-[60%] w-full translate-y-full flex-col items-center gap-3 opacity-0 transition-all", "z-30 flex h-[60%] w-full translate-y-full flex-col items-center gap-3 opacity-0 transition-all",
{ {
"translate-y-0 opacity-100": apparition >= 3, "!translate-y-0 opacity-100": apparition >= 3,
}, },
{ {
"md:min-w-64": top.length < 2, "md:min-w-64": top.length < 2,
@@ -110,7 +153,7 @@ export default function Podium({ data: { subject, top } }) {
className={clsx( className={clsx(
"z-10 flex h-[40%] w-full translate-y-full flex-col items-center gap-3 opacity-0 transition-all", "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,
}, },
)} )}
> >

View File

@@ -1,19 +1,27 @@
import CricleCheck from "@/components/icons/CricleCheck" import CricleCheck from "@/components/icons/CricleCheck"
import CricleXmark from "@/components/icons/CricleXmark" import CricleXmark from "@/components/icons/CricleXmark"
import { SFX_RESULTS_SOUND } from "@/constants"
import { usePlayerContext } from "@/context/player" import { usePlayerContext } from "@/context/player"
import { useEffect } from "react" import { useEffect } from "react"
import useSound from "use-sound"
export default function Result({ export default function Result({
data: { correct, message, points, myPoints, totalPlayer, rank, aheadOfMe }, data: { correct, message, points, myPoints, totalPlayer, rank, aheadOfMe },
}) { }) {
const { dispatch } = usePlayerContext() const { dispatch } = usePlayerContext()
const [sfxResults] = useSound(SFX_RESULTS_SOUND, {
volume: 0.2,
})
useEffect(() => { useEffect(() => {
dispatch({ dispatch({
type: "UPDATE", type: "UPDATE",
payload: { points: myPoints }, payload: { points: myPoints },
}) })
}, [])
sfxResults()
}, [sfxResults])
return ( return (
<section className="anim-show relative mx-auto flex w-full max-w-7xl flex-1 flex-col items-center justify-center"> <section className="anim-show relative mx-auto flex w-full max-w-7xl flex-1 flex-col items-center justify-center">

View File

@@ -1,18 +1,26 @@
import { SFX_BOUMP_SOUND } from "@/constants"
import { useSocketContext } from "@/context/socket" import { useSocketContext } from "@/context/socket"
import clsx from "clsx" import clsx from "clsx"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import useSound from "use-sound"
export default function Start({ data: { time, subject } }) { export default function Start({ data: { time, subject } }) {
const { socket } = useSocketContext() const { socket } = useSocketContext()
const [showTitle, setShowTitle] = useState(true) const [showTitle, setShowTitle] = useState(true)
const [cooldown, setCooldown] = useState(time) const [cooldown, setCooldown] = useState(time)
const [sfxBoump] = useSound(SFX_BOUMP_SOUND, {
volume: 0.2,
})
useEffect(() => { useEffect(() => {
socket.on("game:startCooldown", () => { socket.on("game:startCooldown", () => {
sfxBoump()
setShowTitle(false) setShowTitle(false)
}) })
socket.on("game:cooldown", (sec) => { socket.on("game:cooldown", (sec) => {
sfxBoump()
setCooldown(sec) setCooldown(sec)
}) })
@@ -20,7 +28,7 @@ export default function Start({ data: { time, subject } }) {
socket.off("game:startCooldown") socket.off("game:startCooldown")
socket.off("game:cooldown") socket.off("game:cooldown")
} }
}, []) }, [sfxBoump])
return ( return (
<section className="relative mx-auto flex w-full max-w-7xl flex-1 flex-col items-center justify-center"> <section className="relative mx-auto flex w-full max-w-7xl flex-1 flex-col items-center justify-center">

View File

@@ -56,3 +56,8 @@ export const SFX_ANSWERS_MUSIC = "/sounds/answersMusic.mp3"
export const SFX_ANSWERS_SOUND = "/sounds/answersSound.mp3" export const SFX_ANSWERS_SOUND = "/sounds/answersSound.mp3"
export const SFX_RESULTS_SOUND = "/sounds/results.mp3" export const SFX_RESULTS_SOUND = "/sounds/results.mp3"
export const SFX_SHOW_SOUND = "/sounds/show.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"

View File

@@ -67,7 +67,7 @@
top: -50%; top: -50%;
left: -50%; left: -50%;
} }
95% { 98% {
opacity: 1; opacity: 1;
} }
100% { 100% {