Skip to content

Commit eed7de5

Browse files
authored
Merge pull request #29 from devklick/fix/28_OverlappingAudio
fix: prevent overlapping sound effects
2 parents bf9adf0 + 8a209b5 commit eed7de5

File tree

4 files changed

+49
-26
lines changed

4 files changed

+49
-26
lines changed

src/components/Table/Table.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import useAudioPlayer from "./hooks/useAudioPlayer";
1313

1414
const Table = ({ hide = false }: { hide?: boolean }) => {
1515
const game = useGame();
16-
const {play} = useAudioPlayer();
16+
const { play } = useAudioPlayer();
1717
const { hitWarningsEnabled, stickWarningsEnabled } = useGameSettingsStore();
1818
const [showHitWarning, setShowHitWarning] = useState<boolean>(false);
1919
const [showStickWarning, setShowStickWarning] = useState<boolean>(false);
@@ -31,7 +31,7 @@ const Table = ({ hide = false }: { hide?: boolean }) => {
3131
game.getParticipantScore("Player") >= 18 &&
3232
!overrideWarning
3333
) {
34-
play('warning');
34+
play("warning");
3535
setShowHitWarning(true);
3636
return;
3737
}
@@ -47,7 +47,7 @@ const Table = ({ hide = false }: { hide?: boolean }) => {
4747
game.getParticipantScore("Player") <= 10 &&
4848
!overrideWarning
4949
) {
50-
play('warning');
50+
play("warning");
5151
setShowStickWarning(true);
5252
return;
5353
}

src/components/Table/hooks/useAudioPlayer.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import cardDealt from "../../../assets/audio/DardDealt.mp3";
1+
import cardDealt from "../../../assets/audio/CardDealt.mp3";
22
import roundLost from "../../../assets/audio/RoundLost.mp3";
33
import roundWon from "../../../assets/audio/RoundWon.mp3";
44
import warning from "../../../assets/audio/WarningAlert.mp3";
5+
56
import { useGameSettingsStore } from "../../../stores/gameSettingsStore";
67

78
type SoundEffect = "cardDealt" | "warning" | "roundWon" | "roundLost";
@@ -17,7 +18,8 @@ function useAudioPlayer() {
1718
const { audioEnabled } = useGameSettingsStore();
1819

1920
function play(soundEffect: SoundEffect) {
20-
audioEnabled && new Audio(sounds[soundEffect]).play();
21+
if (!audioEnabled) return;
22+
new Audio(sounds[soundEffect]).play();
2123
}
2224

2325
return { play };

src/components/Table/hooks/useGame.tsx

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ export type WinType =
2323
| "high-card"
2424
| "draw";
2525

26-
const delayBetweenCards = 400;
26+
/**
27+
* A delay used to prevent actions from happening too quickly,
28+
* which would detract from the user experience in the UI.
29+
*
30+
* For example, this delay happens between cards being dealt,
31+
* and between the final card being dealt and the result being displayed.
32+
*/
33+
const delayBetweenActions = 400;
2734

2835
export function useGame() {
2936
const [state, setState] = useState<GameState>("WaitingForStart");
@@ -34,13 +41,13 @@ export function useGame() {
3441
const player = useCardPile();
3542
const dealer = useCardPile();
3643
const stats = useGameStats();
37-
const {play} = useAudioPlayer();
44+
const { play } = useAudioPlayer();
3845

3946
const dealPlayerCard = state === "DealPlayerCard";
4047
const dealDealerCard = state === "DealDealerCard";
4148
const resultGame = state === "Result";
4249
const dealerRound = state === "DealerRound";
43-
50+
4451
/**
4552
* Takes card of determining the winner
4653
* when the game state changes to Result
@@ -50,7 +57,11 @@ export function useGame() {
5057

5158
const gameResult = determineWinner(player.hand, dealer.hand);
5259

53-
setResult(gameResult.winnerText, gameResult.winner);
60+
const timeout = setResult(gameResult.winnerText, gameResult.winner);
61+
62+
return () => {
63+
clearTimeout(timeout);
64+
};
5465

5566
// eslint-disable-next-line react-hooks/exhaustive-deps
5667
}, [resultGame]);
@@ -61,11 +72,15 @@ export function useGame() {
6172
* to go bust or hit a five card trick.
6273
*/
6374
useEffect(() => {
75+
let timeout: NodeJS.Timeout;
6476
if (player.bust) {
65-
setResult("Player bust, dealer wins!", "Dealer");
77+
timeout = setResult("Player bust, dealer wins!", "Dealer");
6678
} else if (player.fiveCardTrick) {
67-
setResult("Player wins with a five card trick!", "Player");
79+
timeout = setResult("Player wins with a five card trick!", "Player");
6880
}
81+
return () => {
82+
timeout && clearTimeout(timeout);
83+
};
6984
// eslint-disable-next-line react-hooks/exhaustive-deps
7085
}, [player.bust, player.fiveCardTrick]);
7186

@@ -81,15 +96,18 @@ export function useGame() {
8196
let timeout: NodeJS.Timeout | undefined;
8297

8398
if (dealer.bust) {
84-
setResult("Dealer bust, player wins!", "Player");
99+
timeout = setResult("Dealer bust, player wins!", "Player");
85100
} else if (dealer.fiveCardTrick) {
86-
setResult("Dealer wins with a five card trick!", "Dealer");
101+
timeout = setResult("Dealer wins with a five card trick!", "Dealer");
87102
}
88103
// Dealer has to hit if they've got less than 16 or less than the players score.
89104
else if (dealerScore >= 16 && dealerScore > playerScore) {
90105
setState("Result");
91106
} else {
92-
timeout = setTimeout(() => dealCardsToParticipant("Dealer", 1), delayBetweenCards);
107+
timeout = setTimeout(
108+
() => dealCardsToParticipant("Dealer", 1),
109+
delayBetweenActions
110+
);
93111
}
94112

95113
return () => {
@@ -109,7 +127,7 @@ export function useGame() {
109127
const timeout = setTimeout(() => {
110128
player.addCards(deck.take(1));
111129
setState("DealDealerCard");
112-
}, delayBetweenCards);
130+
}, delayBetweenActions);
113131

114132
return () => {
115133
clearTimeout(timeout);
@@ -134,7 +152,7 @@ export function useGame() {
134152
} else {
135153
setState("DealPlayerCard");
136154
}
137-
}, delayBetweenCards);
155+
}, delayBetweenActions);
138156

139157
return () => {
140158
clearTimeout(timeout);
@@ -207,17 +225,20 @@ export function useGame() {
207225
* @param outcomeText The text to be displayed to describe the outcome
208226
* @param winner The participant that won the game, if any.
209227
*/
210-
function setResult(outcomeText: string, winner?: Participant | null): void {
211-
setState("GameOver");
212-
setOutcome(outcomeText);
213-
setWinner(winner ?? "none");
214-
if (winner) {
215-
play(winner === 'Player' ? 'roundWon' : 'roundLost' );
216-
}
217-
218-
228+
function setResult(
229+
outcomeText: string,
230+
winner?: Participant | null
231+
): NodeJS.Timeout {
232+
return setTimeout(() => {
233+
setState("GameOver");
234+
setOutcome(outcomeText);
235+
setWinner(winner ?? "none");
236+
if (winner) {
237+
play(winner === "Player" ? "roundWon" : "roundLost");
238+
}
219239

220-
winner && stats.updateWinnerStats(winner);
240+
winner && stats.updateWinnerStats(winner);
241+
}, delayBetweenActions);
221242
}
222243

223244
return {

0 commit comments

Comments
 (0)