diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameController.java index 61d28bc..2b9610c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/CasinoGameController.java @@ -12,6 +12,7 @@ import ch.unibas.dmi.dbis.cs108.casono.client.game.PlayerState; import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService; import ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.gameuicomponents.PlayerStatusController; import ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.gameuicomponents.TaskbarController; +import ch.unibas.dmi.dbis.cs108.casono.ui.sound.SoundManager; import java.io.IOException; import java.net.URL; import java.util.HashSet; @@ -65,6 +66,7 @@ public class CasinoGameController { private Image dealerImage; private javafx.animation.Timeline timeline; private boolean gameStarted = false; + private boolean firstCardUpdate = true; private java.util.List lastCommunityKeys = java.util.List.of(); private java.util.List lastMyCardKeys = java.util.List.of(); private int lastPot = Integer.MIN_VALUE; @@ -178,6 +180,38 @@ public class CasinoGameController { return suit + ":" + value; } + /** + * Count how many new non-null card keys were added when transitioning from old keys to new + * keys. + * + * @param oldKeys The previous list of card keys + * @param newKeys The new list of card keys + * @return The count of new (non-null) cards that were revealed + */ + private int countNewCards(java.util.List oldKeys, java.util.List newKeys) { + int count = 0; + int minSize = Math.min(oldKeys.size(), newKeys.size()); + + // Count cards that changed from "null" to actual card + for (int i = 0; i < minSize; i++) { + String oldKey = oldKeys.get(i); + String newKey = newKeys.get(i); + if ("null".equals(oldKey) && !"null".equals(newKey)) { + count++; + } + } + + // Count any new cards beyond the previous size (if applicable) + for (int i = minSize; i < newKeys.size(); i++) { + String newKey = newKeys.get(i); + if (!"null".equals(newKey)) { + count++; + } + } + + return Math.max(1, count); // At least play one sound if cards changed + } + /** * Generate a list of unique keys for a list of cards. * @@ -577,14 +611,28 @@ public class CasinoGameController { var newCommunityKeys = cardKeys(community, TOTAL_SLOTS); if (!newCommunityKeys.equals(lastCommunityKeys)) { + int newCardCount = countNewCards(lastCommunityKeys, newCommunityKeys); lastCommunityKeys = newCommunityKeys; renderCommunityCards(community); + if (!firstCardUpdate) { + SoundManager.getInstance().playCardRevealMultiple(newCardCount); + } } var newMyCardKeys = cardKeys(myCards, PLAYER_SLOTS); if (!newMyCardKeys.equals(lastMyCardKeys)) { + int newCardCount = countNewCards(lastMyCardKeys, newMyCardKeys); lastMyCardKeys = newMyCardKeys; renderPlayerCards(myCards); + // Don't play sound on first card update (initial animation) + if (!firstCardUpdate) { + SoundManager.getInstance().playCardRevealMultiple(newCardCount); + } + } + + // After first update, enable sounds for subsequent card reveals + if (firstCardUpdate) { + firstCardUpdate = false; } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/TaskbarController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/TaskbarController.java index ded5048..53583f2 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/TaskbarController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/gameui/gameuicomponents/TaskbarController.java @@ -8,6 +8,7 @@ import ch.unibas.dmi.dbis.cs108.casono.client.game.PlayerId; import ch.unibas.dmi.dbis.cs108.casono.client.game.PlayerState; import ch.unibas.dmi.dbis.cs108.casono.client.network.LobbyClient; import ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui.Casinomainui; +import ch.unibas.dmi.dbis.cs108.casono.ui.sound.SoundManager; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; @@ -319,7 +320,7 @@ public class TaskbarController { // Integer targetBet = resolveTargetBet(ActionType.RAISE_BUTTON, lastState); // if (targetBet == null) { - // return ""; + // return ""; // } // int totalContribution = Math.max(0, targetBet); @@ -412,7 +413,7 @@ public class TaskbarController { boolean phaseChanged) { // boolean firstPlayerNewRound = - // phaseChanged && isFirstPreflopPlayer(state, me); + // phaseChanged && isFirstPreflopPlayer(state, me); inputActionAllowed = false; if (!isMyTurn || isOutOrFinished || state == null || me == null) { setBetButtonVisible(false); @@ -1374,18 +1375,21 @@ public class TaskbarController { */ @FXML private void onInputSubmittedAction() { + SoundManager.getInstance().playButtonClick(); processBet(); } /** Called when the Call button is clicked. */ @FXML private void onInputPlayerCall() { + SoundManager.getInstance().playButtonClick(); submitAction(ActionType.CALL_BUTTON); } /** Called when the Fold button is clicked. */ @FXML private void onInputPlayerFold() { + SoundManager.getInstance().playButtonClick(); if (gameService == null) { LOGGER.error("GameService not initialized"); @@ -1409,6 +1413,7 @@ public class TaskbarController { /** Called when the Raise button is clicked. */ @FXML private void onInputPlayerRaise() { + SoundManager.getInstance().playButtonClick(); submitPresetInputAndProcess("raise"); } @@ -1450,6 +1455,7 @@ public class TaskbarController { */ @FXML private void onExitButtonClick() { + SoundManager.getInstance().playButtonClick(); javafx.application.Platform.runLater( () -> { // Close game stage @@ -1534,6 +1540,7 @@ public class TaskbarController { */ @FXML private void onBrowserButtonClick() { + SoundManager.getInstance().playButtonClick(); try { Path path = Paths.get( @@ -1553,6 +1560,7 @@ public class TaskbarController { /** Opens the highscore popup window from the taskbar. */ @FXML private void onHighscoreButtonClick() { + SoundManager.getInstance().playButtonClick(); try { var shared = ClientApp.getSharedClientService(); if (shared == null || shared.isOffline()) {