Feat: Add button cklick and card draw sounds to gameUI

This commit is contained in:
Jona Walpert
2026-04-30 11:37:22 +02:00
parent cf52d293a4
commit ba1249bf93
2 changed files with 58 additions and 2 deletions
@@ -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.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.PlayerStatusController;
import ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.gameuicomponents.TaskbarController; 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.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.HashSet; import java.util.HashSet;
@@ -65,6 +66,7 @@ public class CasinoGameController {
private Image dealerImage; private Image dealerImage;
private javafx.animation.Timeline timeline; private javafx.animation.Timeline timeline;
private boolean gameStarted = false; private boolean gameStarted = false;
private boolean firstCardUpdate = true;
private java.util.List<String> lastCommunityKeys = java.util.List.of(); private java.util.List<String> lastCommunityKeys = java.util.List.of();
private java.util.List<String> lastMyCardKeys = java.util.List.of(); private java.util.List<String> lastMyCardKeys = java.util.List.of();
private int lastPot = Integer.MIN_VALUE; private int lastPot = Integer.MIN_VALUE;
@@ -178,6 +180,38 @@ public class CasinoGameController {
return suit + ":" + value; 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<String> oldKeys, java.util.List<String> 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. * Generate a list of unique keys for a list of cards.
* *
@@ -577,14 +611,28 @@ public class CasinoGameController {
var newCommunityKeys = cardKeys(community, TOTAL_SLOTS); var newCommunityKeys = cardKeys(community, TOTAL_SLOTS);
if (!newCommunityKeys.equals(lastCommunityKeys)) { if (!newCommunityKeys.equals(lastCommunityKeys)) {
int newCardCount = countNewCards(lastCommunityKeys, newCommunityKeys);
lastCommunityKeys = newCommunityKeys; lastCommunityKeys = newCommunityKeys;
renderCommunityCards(community); renderCommunityCards(community);
if (!firstCardUpdate) {
SoundManager.getInstance().playCardRevealMultiple(newCardCount);
}
} }
var newMyCardKeys = cardKeys(myCards, PLAYER_SLOTS); var newMyCardKeys = cardKeys(myCards, PLAYER_SLOTS);
if (!newMyCardKeys.equals(lastMyCardKeys)) { if (!newMyCardKeys.equals(lastMyCardKeys)) {
int newCardCount = countNewCards(lastMyCardKeys, newMyCardKeys);
lastMyCardKeys = newMyCardKeys; lastMyCardKeys = newMyCardKeys;
renderPlayerCards(myCards); 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;
} }
} }
@@ -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.game.PlayerState;
import ch.unibas.dmi.dbis.cs108.casono.client.network.LobbyClient; 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.client.ui.lobbyui.Casinomainui;
import ch.unibas.dmi.dbis.cs108.casono.ui.sound.SoundManager;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Optional; import java.util.Optional;
@@ -319,7 +320,7 @@ public class TaskbarController {
// Integer targetBet = resolveTargetBet(ActionType.RAISE_BUTTON, lastState); // Integer targetBet = resolveTargetBet(ActionType.RAISE_BUTTON, lastState);
// if (targetBet == null) { // if (targetBet == null) {
// return ""; // return "";
// } // }
// int totalContribution = Math.max(0, targetBet); // int totalContribution = Math.max(0, targetBet);
@@ -412,7 +413,7 @@ public class TaskbarController {
boolean phaseChanged) { boolean phaseChanged) {
// boolean firstPlayerNewRound = // boolean firstPlayerNewRound =
// phaseChanged && isFirstPreflopPlayer(state, me); // phaseChanged && isFirstPreflopPlayer(state, me);
inputActionAllowed = false; inputActionAllowed = false;
if (!isMyTurn || isOutOrFinished || state == null || me == null) { if (!isMyTurn || isOutOrFinished || state == null || me == null) {
setBetButtonVisible(false); setBetButtonVisible(false);
@@ -1374,18 +1375,21 @@ public class TaskbarController {
*/ */
@FXML @FXML
private void onInputSubmittedAction() { private void onInputSubmittedAction() {
SoundManager.getInstance().playButtonClick();
processBet(); processBet();
} }
/** Called when the Call button is clicked. */ /** Called when the Call button is clicked. */
@FXML @FXML
private void onInputPlayerCall() { private void onInputPlayerCall() {
SoundManager.getInstance().playButtonClick();
submitAction(ActionType.CALL_BUTTON); submitAction(ActionType.CALL_BUTTON);
} }
/** Called when the Fold button is clicked. */ /** Called when the Fold button is clicked. */
@FXML @FXML
private void onInputPlayerFold() { private void onInputPlayerFold() {
SoundManager.getInstance().playButtonClick();
if (gameService == null) { if (gameService == null) {
LOGGER.error("GameService not initialized"); LOGGER.error("GameService not initialized");
@@ -1409,6 +1413,7 @@ public class TaskbarController {
/** Called when the Raise button is clicked. */ /** Called when the Raise button is clicked. */
@FXML @FXML
private void onInputPlayerRaise() { private void onInputPlayerRaise() {
SoundManager.getInstance().playButtonClick();
submitPresetInputAndProcess("raise"); submitPresetInputAndProcess("raise");
} }
@@ -1450,6 +1455,7 @@ public class TaskbarController {
*/ */
@FXML @FXML
private void onExitButtonClick() { private void onExitButtonClick() {
SoundManager.getInstance().playButtonClick();
javafx.application.Platform.runLater( javafx.application.Platform.runLater(
() -> { () -> {
// Close game stage // Close game stage
@@ -1534,6 +1540,7 @@ public class TaskbarController {
*/ */
@FXML @FXML
private void onBrowserButtonClick() { private void onBrowserButtonClick() {
SoundManager.getInstance().playButtonClick();
try { try {
Path path = Path path =
Paths.get( Paths.get(
@@ -1553,6 +1560,7 @@ public class TaskbarController {
/** Opens the highscore popup window from the taskbar. */ /** Opens the highscore popup window from the taskbar. */
@FXML @FXML
private void onHighscoreButtonClick() { private void onHighscoreButtonClick() {
SoundManager.getInstance().playButtonClick();
try { try {
var shared = ClientApp.getSharedClientService(); var shared = ClientApp.getSharedClientService();
if (shared == null || shared.isOffline()) { if (shared == null || shared.isOffline()) {