Fix: loop Animation in Game-UI

This commit is contained in:
Julian Kropff
2026-04-12 20:11:10 +02:00
parent 06c059ce5e
commit fb593d48a6
2 changed files with 57 additions and 29 deletions
@@ -13,9 +13,17 @@ import java.util.logging.Logger;
/**
* Fetches and parses game state from server.
*
* Protocol notes (based on your logs):
* - Success replies contain lines like PHASE=..., POT=..., PLAYER ... END ... END
* - Error replies contain -ERR, CODE=..., MSG=..., END
* Protocol notes (based on your current server implementation):
* - Success replies contain: PHASE, POT, CURRENT_BET, DEALER, ACTIVE_PLAYER, then blocks:
* - CARD ... END (community cards on root level)
* - PLAYER ... (NAME/CHIPS/BET/STATE + optional CARD blocks for requesting player) ... END
* - Error replies contain: -ERR then CODE=..., MSG=..., END
*
* Important:
* - The server does NOT wrap cards in a "CARDS" container.
* - CARD blocks appear either:
* - at root level -> community cards
* - inside PLAYER -> hole cards for that player (usually only for the requesting user)
*/
public class GameClient {
@@ -51,7 +59,7 @@ public class GameClient {
String joined = String.join("\n", lines);
if (joined.contains("-ERR")) {
if (joined.contains("-ERR") || joined.contains("-ERROR")) {
String code = extractValue(joined, "CODE");
String msg = extractValue(joined, "MSG");
LOG.info(() -> "GET_GAME_STATE returned -ERR code=" + code + " msg=" + msg);
@@ -100,14 +108,12 @@ public class GameClient {
Player currentPlayer = null;
Card currentCard = null;
boolean inPlayerCards = false;
boolean inCommunityCards = false;
for (String raw : input.split("\n")) {
String line = raw.trim();
if (line.isEmpty()) continue;
if (line.startsWith("+OK")) continue;
// Global fields
if (line.startsWith("PHASE=")) {
s.phase = value(line);
continue;
@@ -136,24 +142,21 @@ public class GameClient {
if (line.equals("PLAYER")) {
currentPlayer = new Player();
s.players.add(currentPlayer);
inPlayerCards = false;
currentCard = null;
continue;
}
if (line.equals("CARDS")) {
inPlayerCards = (currentPlayer != null);
inCommunityCards = (currentPlayer == null);
currentCard = null;
continue;
}
if (line.startsWith("CARD")) {
if (line.equals("CARD")) {
currentCard = new Card("", "");
if (inPlayerCards && currentPlayer != null) {
currentPlayer.addCard(currentCard);
} else if (inCommunityCards) {
s.communityCards.add(currentCard);
if (currentPlayer != null) {
currentPlayer.addCard(currentCard); // hole card
} else {
s.communityCards.add(currentCard); // community card
}
continue;
}
@@ -162,7 +165,6 @@ public class GameClient {
currentCard.setValue(value(line));
continue;
}
if (line.startsWith("SUIT=") && currentCard != null) {
currentCard.setSuit(value(line));
continue;
@@ -173,18 +175,12 @@ public class GameClient {
currentCard = null;
continue;
}
if (inPlayerCards) {
inPlayerCards = false;
continue;
}
if (inCommunityCards) {
inCommunityCards = false;
continue;
}
if (currentPlayer != null) {
currentPlayer = null;
continue;
}
continue;
}
@@ -51,6 +51,9 @@ public class CasinoGameController {
private Image dealerImage;
private javafx.animation.Timeline timeline;
private boolean gameStarted = false;
private java.util.List<String> lastCommunityKeys = java.util.List.of();
private java.util.List<String> lastMyCardKeys = java.util.List.of();
private int lastPot = Integer.MIN_VALUE;
private static final int TOTAL_SLOTS = 5;
private static final int PLAYER_SLOTS = 2;
@@ -126,6 +129,22 @@ public class CasinoGameController {
// default constructor for FXML
}
private String cardKey(Card c) {
if (c == null) return "null";
String suit = (c.getSuit() == null) ? "" : c.getSuit().toLowerCase();
String value = (c.getValue() == null) ? "" : c.getValue().toLowerCase();
return suit + ":" + value;
}
private java.util.List<String> cardKeys(java.util.List<Card> cards, int slots) {
java.util.List<String> keys = new java.util.ArrayList<>(slots);
for (int i = 0; i < slots; i++) {
Card c = (cards != null && i < cards.size()) ? cards.get(i) : null;
keys.add(cardKey(c));
}
return java.util.List.copyOf(keys);
}
/**
* Set the GameService for this controller. This method must be called before starting the UI to
* ensure that the controller has access to the game logic and can update the interface
@@ -356,15 +375,28 @@ public class CasinoGameController {
List<Player> players = (s.players != null) ? s.players : List.of();
List<Card> community = (s.communityCards != null) ? s.communityCards : List.of();
List<Card> myCards = getMyCards(players);
renderCommunityCards(community);
renderPlayerCards(getMyCards(players));
renderPot(s.pot);
java.util.List<String> newCommunityKeys = cardKeys(community, TOTAL_SLOTS);
if (!newCommunityKeys.equals(lastCommunityKeys)) {
lastCommunityKeys = newCommunityKeys;
renderCommunityCards(community);
}
java.util.List<String> newMyCardKeys = cardKeys(myCards, PLAYER_SLOTS);
if (!newMyCardKeys.equals(lastMyCardKeys)) {
lastMyCardKeys = newMyCardKeys;
renderPlayerCards(myCards);
}
if (s.pot != lastPot) {
lastPot = s.pot;
renderPot(s.pot);
}
updatePlayers(players);
updateGameInfo(s);
highlightDealer(s);
updateTaskbar(s);
LOGGER.info("myPlayerId=" + myPlayerId);