Skip to content

Commit 92bca68

Browse files
authored
Merge pull request #23 from devklick/feature/19_SoundEffects
Feature/19 sound effects
2 parents 6b8661b + ae660d2 commit 92bca68

File tree

11 files changed

+75
-5
lines changed

11 files changed

+75
-5
lines changed

src/assets/audio/DardDealt.mp3

11.7 KB
Binary file not shown.

src/assets/audio/RoundLost.mp3

25.2 KB
Binary file not shown.

src/assets/audio/RoundWon.mp3

37.4 KB
Binary file not shown.

src/assets/audio/WarningAlert.mp3

17.2 KB
Binary file not shown.

src/components/Card/hooks/useCardPile.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useRef, useState } from "react";
22
import { CardObject, Facing } from "../card.types";
33
import { BestHand, calculateBestHand } from "../../../utilities/deckUtilities";
4+
import useAudioPlayer from "../../Table/hooks/useAudioPlayer";
45

56
const defaultBestHand: BestHand = { cards: [], score: 0 };
67
/**
@@ -13,14 +14,18 @@ export function useCardPile() {
1314
const bust = useRef<boolean>(false);
1415
const fiveCardTrick = useRef<boolean>(false);
1516
const allCardsVisible = useRef<boolean>(false);
17+
const {play} = useAudioPlayer();
1618

1719
/**
1820
* Add cards to the pile
1921
* @param cardsToAdd The cards to be added to the pile
2022
* @param facing The direction the card should be facing when placed in the pile
2123
*/
2224
function addCards(cardsToAdd: CardObject[], facing: Facing | null = null) {
23-
if (facing) cardsToAdd.forEach((c) => (c.facing = facing));
25+
cardsToAdd.forEach(card => {
26+
play('cardDealt');
27+
if (facing) card.facing = facing;
28+
});
2429
setCards([...cards].concat(cardsToAdd));
2530
}
2631

src/components/GameSettings/GameSettings.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ function GameSettings() {
3333
</div>
3434
</div>
3535

36+
<div className={styles.GameSetting}>
37+
<div className={styles.Info}>
38+
<span className={styles.Header}>Audio Enabled</span>
39+
<span className={styles.Description}>
40+
Whether or not sound effects should play
41+
</span>
42+
</div>
43+
<div className={styles.ControlWrapper}>
44+
<CheckBox
45+
className={styles.Control}
46+
checked={gameSettings.audioEnabled}
47+
onChanged={() => gameSettings.toggleAudioEnabled()}
48+
/>
49+
</div>
50+
</div>
51+
3652
<div className={styles.GameSetting}>
3753
<div className={styles.Info}>
3854
<span className={styles.Header}>Hit Warnings Enabled</span>

src/components/Table/Table.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import { useGameSettingsStore } from "../../stores/gameSettingsStore";
99
import styles from "./Table.module.scss";
1010
import SettingsButton from "../SettingsButton";
1111
import { CardEffect } from "../Card/Card";
12+
import useAudioPlayer from "./hooks/useAudioPlayer";
1213

1314
const Table = ({ hide = false }: { hide?: boolean }) => {
1415
const game = useGame();
16+
const {play} = useAudioPlayer();
1517
const { hitWarningsEnabled, stickWarningsEnabled } = useGameSettingsStore();
1618
const [showHitWarning, setShowHitWarning] = useState<boolean>(false);
1719
const [showStickWarning, setShowStickWarning] = useState<boolean>(false);
@@ -29,6 +31,7 @@ const Table = ({ hide = false }: { hide?: boolean }) => {
2931
game.getParticipantScore("Player") >= 18 &&
3032
!overrideWarning
3133
) {
34+
play('warning');
3235
setShowHitWarning(true);
3336
return;
3437
}
@@ -44,6 +47,7 @@ const Table = ({ hide = false }: { hide?: boolean }) => {
4447
game.getParticipantScore("Player") <= 10 &&
4548
!overrideWarning
4649
) {
50+
play('warning');
4751
setShowStickWarning(true);
4852
return;
4953
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import cardDealt from "../../../assets/audio/DardDealt.mp3";
2+
import roundLost from "../../../assets/audio/RoundLost.mp3";
3+
import roundWon from "../../../assets/audio/RoundWon.mp3";
4+
import warning from "../../../assets/audio/WarningAlert.mp3";
5+
import { useGameSettingsStore } from "../../../stores/gameSettingsStore";
6+
7+
type SoundEffect = "cardDealt" | "warning" | "roundWon" | "roundLost";
8+
9+
const sounds: Record<SoundEffect, string> = {
10+
cardDealt,
11+
roundLost,
12+
roundWon,
13+
warning,
14+
};
15+
16+
function useAudioPlayer() {
17+
const { audioEnabled } = useGameSettingsStore();
18+
19+
function play(soundEffect: SoundEffect) {
20+
audioEnabled && new Audio(sounds[soundEffect]).play();
21+
}
22+
23+
return { play };
24+
}
25+
export default useAudioPlayer;

src/components/Table/hooks/useGame.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
22
import { useGameStats } from "../../InfoHud";
33
import { determineWinner } from "../../../utilities/deckUtilities";
44
import { Facing, useCardPile, useDeck } from "../../Card";
5+
import useAudioPlayer from "./useAudioPlayer";
56

67
export type GameState =
78
| "WaitingForStart"
@@ -22,6 +23,8 @@ export type WinType =
2223
| "high-card"
2324
| "draw";
2425

26+
const delayBetweenCards = 400;
27+
2528
export function useGame() {
2629
const [state, setState] = useState<GameState>("WaitingForStart");
2730
const [outcome, setOutcome] = useState<string | null>(null);
@@ -31,12 +34,13 @@ export function useGame() {
3134
const player = useCardPile();
3235
const dealer = useCardPile();
3336
const stats = useGameStats();
37+
const {play} = useAudioPlayer();
3438

3539
const dealPlayerCard = state === "DealPlayerCard";
3640
const dealDealerCard = state === "DealDealerCard";
3741
const resultGame = state === "Result";
3842
const dealerRound = state === "DealerRound";
39-
43+
4044
/**
4145
* Takes card of determining the winner
4246
* when the game state changes to Result
@@ -85,7 +89,7 @@ export function useGame() {
8589
else if (dealerScore >= 16 && dealerScore > playerScore) {
8690
setState("Result");
8791
} else {
88-
timeout = setTimeout(() => dealCardsToParticipant("Dealer", 1), 500);
92+
timeout = setTimeout(() => dealCardsToParticipant("Dealer", 1), delayBetweenCards);
8993
}
9094

9195
return () => {
@@ -105,7 +109,7 @@ export function useGame() {
105109
const timeout = setTimeout(() => {
106110
player.addCards(deck.take(1));
107111
setState("DealDealerCard");
108-
}, 500);
112+
}, delayBetweenCards);
109113

110114
return () => {
111115
clearTimeout(timeout);
@@ -130,7 +134,7 @@ export function useGame() {
130134
} else {
131135
setState("DealPlayerCard");
132136
}
133-
}, 500);
137+
}, delayBetweenCards);
134138

135139
return () => {
136140
clearTimeout(timeout);
@@ -207,6 +211,11 @@ export function useGame() {
207211
setState("GameOver");
208212
setOutcome(outcomeText);
209213
setWinner(winner ?? "none");
214+
if (winner) {
215+
play(winner === 'Player' ? 'roundWon' : 'roundLost' );
216+
}
217+
218+
210219

211220
winner && stats.updateWinnerStats(winner);
212221
}

src/react-app-env.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
/// <reference types="react-scripts" />
2+
3+
declare module "*.mp3" {
4+
const src: string;
5+
export default src;
6+
}

0 commit comments

Comments
 (0)