Skip to content

Commit

Permalink
Feat: Sound Setup (#305)
Browse files Browse the repository at this point in the history
## Description:
This PR introduces the global setup for the game music and sound effects

## Changes
- Implemented a Sound Provider to control sound states
- Volume control for Master Audio, Music and UI Sound Effects
- Menu Dialog UI to manipulate Audio
  • Loading branch information
privilegemendes authored Feb 12, 2024
1 parent 1318a77 commit 3d9a8aa
Show file tree
Hide file tree
Showing 71 changed files with 495 additions and 61 deletions.
Binary file added public/music/Explosion.mp3
Binary file not shown.
Binary file added public/music/Robot_I_am_a_Human.mp3
Binary file not shown.
Binary file added public/music/SingleLazer.mp3
Binary file not shown.
Binary file added public/music/Thunder.mp3
Binary file not shown.
Binary file added public/music/TrippleLazer.mp3
Binary file not shown.
Binary file added public/music/TrippleLazer_Explosion.mp3
Binary file not shown.
Binary file added public/music/Voice Over/BotBusted_HeadPop.mp3
Binary file not shown.
Binary file added public/music/Voice Over/BotBusters.mp3
Binary file not shown.
Binary file added public/music/Voice Over/BotWins.mp3
Binary file not shown.
Binary file added public/music/Voice Over/LetsBustSomeBots.mp3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added public/music/Voice Over/Player Wins/Win_Yeah.mp3
Binary file not shown.
Binary file not shown.
Binary file added public/music/Voice Over/StartChating.mp3
Binary file not shown.
Binary file added public/music/botbusters-theme-song.mp3
Binary file not shown.
3 changes: 3 additions & 0 deletions public/music/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import BotBustersTheme from "./botbusters-theme-song.mp3";

export { BotBustersTheme };
Binary file added public/sounds/BB_UI_Blip.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_Blip_Down.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_Blip_Selection.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_Blip_Up.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_Bonus.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_Denied.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_Nav_Click.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_Play.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_TextRecieved.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_TextSent.mp3
Binary file not shown.
Binary file added public/sounds/BB_UI_Texting.mp3
Binary file not shown.
5 changes: 5 additions & 0 deletions src/assets/text/audio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const audio = {
master: "Master Audio",
music: "Music",
sfx: "Sound Effects",
};
2 changes: 2 additions & 0 deletions src/assets/text/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { navigation } from "./navigation.js";
import { playerProfile } from "./player-profile.js";
import { support } from "./support.js";
import { termsAndConditions } from "./terms-and-conditions.js";
import { audio } from "~/assets/text/audio.js";

export const text = {
auth,
Expand All @@ -32,4 +33,5 @@ export const text = {
howToPlay,
achievements,
support,
audio,
};
83 changes: 83 additions & 0 deletions src/components/audio-settings/audio-settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { type FC, useState } from "react";
import { Button, Menu, Stack, Typography } from "@mui/material";
import { SoundOffIcon, SoundOnIcon } from "~/assets/icons/index.js";
import { VolumeSlider } from "~/components/audio-settings/volume-slider.jsx";
import {
useChangeMasterVolume,
useChangeMusicVolume,
useChangeSFXVolume,
} from "~/hooks/volume.js";
import {
AUDIO_OFF,
DEFAULT_MASTER_VOLUME,
DEFAULT_MUSIC_VOLUME,
DEFAULT_SFX_VOLUME,
} from "~/constants/main.js";
import { styles } from "./styles.js";
import { text } from "~/assets/text/index.js";

export const AudioSettings: FC = () => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);

const handleOpen = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const { changeMasterVolume, masterVolume } = useChangeMasterVolume();
const { changeSFXVolume, sfxVolume } = useChangeSFXVolume();
const { changeMusicVolume, musicVolume } = useChangeMusicVolume();

const handleReset = () => {
changeMasterVolume(DEFAULT_MASTER_VOLUME);
changeSFXVolume(DEFAULT_SFX_VOLUME);
changeMusicVolume(DEFAULT_MUSIC_VOLUME);
};

return (
<>
<Button variant="text" onClick={handleOpen}>
{masterVolume === AUDIO_OFF ? <SoundOffIcon /> : <SoundOnIcon />}
</Button>
<Menu
open={open}
anchorEl={anchorEl}
onClose={() => handleClose()}
transformOrigin={{ horizontal: "right", vertical: "top" }}
anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
MenuListProps={{
sx: styles.menu,
}}
>
<Stack sx={styles.menuItem}>
<Typography variant="caption" sx={styles.text}>
{text.audio.master}
</Typography>
<VolumeSlider
volume={masterVolume}
changeVolume={changeMasterVolume}
/>
</Stack>
<Stack sx={styles.menuItem}>
<Typography variant="caption" sx={styles.text}>
{text.audio.music}
</Typography>
<VolumeSlider volume={musicVolume} changeVolume={changeMusicVolume} />
</Stack>
<Stack sx={styles.menuItem}>
<Typography variant="caption" sx={styles.text}>
{text.audio.sfx}
</Typography>
<VolumeSlider volume={sfxVolume} changeVolume={changeSFXVolume} />
</Stack>
<Stack sx={styles.resetButton}>
<Button variant="text" sx={styles.button} onClick={handleReset}>
Reset to Default
</Button>
</Stack>
</Menu>
</>
);
};
1 change: 1 addition & 0 deletions src/components/audio-settings/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./audio-settings.jsx";
37 changes: 37 additions & 0 deletions src/components/audio-settings/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { theme } from "~/styles/index.js";

export const styles = {
container: {
flexDirection: "column",
},
menu: {
borderRadius: 0,
border: `4px solid ${theme.palette.customGrey.main}`,
},
resetButton: {
flexDirection: "row",
width: "100%",
justifyContent: "center",
alignItems: "center",
p: 2,
},
button: {
fontSize: 16,
lineHeight: "normal",
"&:hover": {
cursor: "pointer",
textDecoration: "underline",
},
},
menuItem: {
flexDirection: "row",
width: "100%",
justifyContent: "space-between",
alignItems: "center",
p: 2,
},
text: {
fontSize: 16,
lineHeight: "normal",
},
};
39 changes: 39 additions & 0 deletions src/components/audio-settings/volume-slider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { FC } from "react";
import { Box, Button, Slider, Stack } from "@mui/material";
import { VolumeDown, VolumeUp } from "@mui/icons-material";
import { AUDIO_OFF, AUDIO_ON } from "~/constants/index.js";

interface Props {
volume: number;
changeVolume: (volume: number) => void;
}
export const VolumeSlider: FC<Props> = ({ volume, changeVolume }) => {
const handleChange = (event: Event, newValue: number | number[]) => {
if (typeof newValue === "number") {
changeVolume(newValue);
} else {
return; // will never be an array
}
};

return (
<Box sx={{ width: 400 }}>
<Stack spacing={2} direction="row" sx={{ mb: 1 }} alignItems="center">
<Button variant="text" onClick={() => changeVolume(AUDIO_OFF)}>
<VolumeDown />
</Button>
<Slider
aria-label="Volume"
value={volume}
onChange={handleChange}
min={AUDIO_OFF}
max={AUDIO_ON}
step={0.1}
/>
<Button variant="text" onClick={() => changeVolume(AUDIO_ON)}>
<VolumeUp />
</Button>
</Stack>
</Box>
);
};
10 changes: 2 additions & 8 deletions src/components/main-menu/main-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ const Transition = forwardRef(function Transition(
interface Props {
open: boolean;
setOpen: (open: boolean) => void;
soundOn: boolean;
setSoundOn: (value: boolean) => void;
}

export const MainMenu: FC<Props> = ({ open, setOpen, soundOn, setSoundOn }) => {
export const MainMenu: FC<Props> = ({ open, setOpen }) => {
const router = useRouter();
const handleClose = () => {
setOpen(false);
Expand All @@ -45,11 +43,7 @@ export const MainMenu: FC<Props> = ({ open, setOpen, soundOn, setSoundOn }) => {
TransitionComponent={Transition}
sx={styles.dialog}
>
<NavbarMenu
soundOn={soundOn}
setSoundOn={setSoundOn}
handleClose={handleClose}
/>
<NavbarMenu handleClose={handleClose} />
<Button
variant="text"
sx={styles.dialogLogo}
Expand Down
24 changes: 5 additions & 19 deletions src/components/main-menu/navbar-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,22 @@ import { Button, Stack, Typography } from "@mui/material";
import { useRouter } from "next/router.js";
import { pages } from "~/router.js";
import { NavbarMenuButton } from "~/components/main-menu/index.js";
import { AudioSettings } from "~/components/audio-settings/index.js";
import { text } from "~/assets/text/index.js";
import { styles } from "~/components/main-menu/styles.js";

import {
BotBustersIcon,
SoundOffIcon,
SoundOnIcon,
UserIcon,
} from "~/assets/icons/index.js";
import { BotBustersIcon, UserIcon } from "~/assets/icons/index.js";
import { api } from "~/utils/api.js";
import { styles } from "~/components/main-menu/styles.js";

interface Props {
handleClose: () => void;
soundOn: boolean;
setSoundOn: (value: boolean) => void;
}

export const NavbarMenu: FC<Props> = ({ handleClose, soundOn, setSoundOn }) => {
export const NavbarMenu: FC<Props> = ({ handleClose }) => {
const router = useRouter();

const loggedUser = api.user.getLoggedUser.useQuery(undefined, {
retry: false,
});

const onSoundClick = () => {
setSoundOn(!soundOn);
};

const handleNavigation = (path: string) => {
void router.push(path);
handleClose();
Expand All @@ -55,9 +43,7 @@ export const NavbarMenu: FC<Props> = ({ handleClose, soundOn, setSoundOn }) => {
<BotBustersIcon />
</Button>
<Stack direction={"row"} rowGap={2} sx={styles.navbarEnd}>
<Button variant="text" onClick={onSoundClick}>
{soundOn ? <SoundOnIcon /> : <SoundOffIcon />}
</Button>
<AudioSettings />
<NavbarMenuButton sx={styles.button} onClick={handleClose} />
</Stack>
</Stack>
Expand Down
34 changes: 9 additions & 25 deletions src/components/navbar/navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,28 @@
import { type FC, useState } from "react";
import { type FC } from "react";
import { Button, Stack, Typography } from "@mui/material";
import { useRouter } from "next/router";
import { text } from "~/assets/text/index.js";

import {
BotBustersIcon,
SoundOffIcon,
SoundOnIcon,
UserIcon,
} from "~/assets/icons/index.js";
import { MenuButton } from "~/components/main-menu/menu-button.jsx";
import { MainMenu } from "~/components/main-menu/index.js";
import { AudioSettings } from "~/components/audio-settings/index.js";

import { BotBustersIcon, UserIcon } from "~/assets/icons/index.js";
import { pages } from "~/router.js";
import { styles } from "./styles.js";
import { text } from "~/assets/text/index.js";
import { api } from "~/utils/api.js";

import { styles } from "./styles.js";

interface Props {
open: boolean;
setOpen: (open: boolean) => void;
}

export const Navbar: FC<Props> = ({ open, setOpen }) => {
const router = useRouter();
const [soundOn, setSoundOn] = useState(true);

const loggedUser = api.user.getLoggedUser.useQuery(undefined, {
retry: false,
});

const onSoundClick = () => {
setSoundOn(!soundOn);
};

const handleNavigation = (path: string) => {
void router.push(path);
};
Expand All @@ -58,18 +49,11 @@ export const Navbar: FC<Props> = ({ open, setOpen }) => {
<BotBustersIcon />
</Button>
<Stack direction={"row"} rowGap={2} sx={styles.navbarEnd}>
<Button variant="text" onClick={onSoundClick}>
{soundOn ? <SoundOnIcon /> : <SoundOffIcon />}
</Button>
<AudioSettings />
<MenuButton sx={styles.button} onClick={() => setOpen(true)} />
</Stack>
</Stack>
<MainMenu
soundOn={soundOn}
setSoundOn={setSoundOn}
open={open}
setOpen={setOpen}
/>
<MainMenu open={open} setOpen={setOpen} />
</Stack>
);
};
21 changes: 19 additions & 2 deletions src/components/play-button/play-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,39 @@ import { type FC } from "react";
import { PlayButtonAnimation } from "~/assets/animations/index.js";
import { AnimationPlayer } from "~/components/animation/index.js";
import { styles } from "./styles.js";
import { usePlaySFX } from "~/hooks/sounds.js";

interface Props {
onClick: () => void;
disabled: boolean;
}

export const PlayButton: FC<Props> = ({ onClick, disabled }) => {
const segments = [
[0, 96],
[24, 96],
];
const playSfx = usePlaySFX();

const handleClick = () => {
void playSfx("./sounds/BB_UI_Play.mp3");
onClick();
};

return (
<Box
component={"button"}
onClick={onClick}
onClick={handleClick}
disabled={disabled}
aria-label={"Start"}
sx={styles.playButton}
>
<AnimationPlayer animationData={PlayButtonAnimation} play loop />
<AnimationPlayer
animationData={PlayButtonAnimation}
segments={segments}
play
loop
/>
</Box>
);
};
7 changes: 7 additions & 0 deletions src/constants/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,10 @@ export const ONE_TIME_ACHIEVEMENTS: AchievementId[] = [
];

export const EMPTY_RES = "empty";

export const AUDIO_ON = 1;
export const AUDIO_OFF = 0;

export const DEFAULT_MASTER_VOLUME = 1;
export const DEFAULT_MUSIC_VOLUME = 0.5;
export const DEFAULT_SFX_VOLUME = 1;
1 change: 1 addition & 0 deletions src/containers/sound-provider/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./sound-provider.jsx";
Loading

0 comments on commit 3d9a8aa

Please sign in to comment.