From 580dbd49502047062cdbbf16dfb1dd43ed2dfdf8 Mon Sep 17 00:00:00 2001 From: milospil Date: Mon, 13 Apr 2026 13:36:03 +0200 Subject: [PATCH] Revert "Merge branch 'main' of git.ntnu.no:milospi/TDT4240gr07-BeatBattle" This reverts commit 3a93d9df47bd0f0848ae8688acdaf557132853cd, reversing changes made to 6f60727a42a58ff14f1a43c976db413b4225712b. --- .../firebase/AndroidFirebaseGateway.java | 9 +-- .../firebase/FirestoreSessionRepository.java | 61 +----------------- .../java/group07/beatbattle/BeatBattle.java | 5 +- .../controller/LeaderboardController.java | 29 --------- .../controller/LobbyController.java | 29 +-------- .../controller/RoundController.java | 24 ++----- .../controller/SettingsController.java | 2 +- .../beatbattle/firebase/FirebaseGateway.java | 5 +- .../firebase/NoOpFirebaseGateway.java | 7 +-- .../beatbattle/{utils => i18n}/Strings.java | 4 +- .../java/group07/beatbattle/model/Player.java | 4 -- .../beatbattle/ui/components/ApplyButton.java | 2 +- .../ui/components/LanguageSelector.java | 2 +- .../ui/components/RoundSelector.java | 2 +- .../ui/components/StartGameButton.java | 2 +- .../group07/beatbattle/view/GameOverView.java | 14 +---- .../beatbattle/view/GameRoundView.java | 15 ++--- .../beatbattle/view/JoinCreateView.java | 4 +- .../beatbattle/view/LeaderboardView.java | 63 +++++++++---------- .../group07/beatbattle/view/LobbyView.java | 27 ++++---- .../group07/beatbattle/view/SettingsView.java | 2 +- .../group07/beatbattle/view/StartView.java | 2 +- 22 files changed, 69 insertions(+), 245 deletions(-) rename core/src/main/java/group07/beatbattle/{utils => i18n}/Strings.java (94%) diff --git a/android/src/main/java/group07/beatbattle/android/firebase/AndroidFirebaseGateway.java b/android/src/main/java/group07/beatbattle/android/firebase/AndroidFirebaseGateway.java index 6195f73..c6fe312 100644 --- a/android/src/main/java/group07/beatbattle/android/firebase/AndroidFirebaseGateway.java +++ b/android/src/main/java/group07/beatbattle/android/firebase/AndroidFirebaseGateway.java @@ -99,8 +99,8 @@ public void listenToSessionState(String sessionId, SessionStateListener listener } @Override - public void updatePlayerScore(String sessionId, String playerId, int score, int roundScore, SimpleCallback callback) { - sessionRepository.updatePlayerScore(sessionId, playerId, score, roundScore, callback); + public void updatePlayerScore(String sessionId, String playerId, int score, SimpleCallback callback) { + sessionRepository.updatePlayerScore(sessionId, playerId, score, callback); } @Override @@ -117,9 +117,4 @@ public void submitAnswer(String sessionId, int roundIndex, String playerId, Simp public void listenToRoundAnswerCount(String sessionId, int roundIndex, AnswerCountCallback callback) { sessionRepository.listenToRoundAnswerCount(sessionId, roundIndex, callback); } - - @Override - public void resetSessionForNewGame(String sessionId, SimpleCallback callback) { - sessionRepository.resetSessionForNewGame(sessionId, callback); - } } diff --git a/android/src/main/java/group07/beatbattle/android/firebase/FirestoreSessionRepository.java b/android/src/main/java/group07/beatbattle/android/firebase/FirestoreSessionRepository.java index dde55d4..d3554d2 100644 --- a/android/src/main/java/group07/beatbattle/android/firebase/FirestoreSessionRepository.java +++ b/android/src/main/java/group07/beatbattle/android/firebase/FirestoreSessionRepository.java @@ -159,11 +159,6 @@ public ListenerRegistration listenToPlayers( player.setScore(scoreValue.intValue()); } - Long roundScoreValue = document.getLong("roundScore"); - if (roundScoreValue != null) { - player.setLastRoundScore(roundScoreValue.intValue()); - } - players.add(player); }); @@ -189,8 +184,6 @@ public void fetchPlayers( Player player = new Player(playerId, name, isHost); Long scoreValue = document.getLong("score"); if (scoreValue != null) player.setScore(scoreValue.intValue()); - Long roundScoreValue = document.getLong("roundScore"); - if (roundScoreValue != null) player.setLastRoundScore(roundScoreValue.intValue()); players.add(player); } callback.onPlayersChanged(players); @@ -350,10 +343,7 @@ public void listenToSessionState( listener.onFailure(error); return; } - if (snapshot == null || !snapshot.exists()) { - listener.onStateChanged("deleted", 0); - return; - } + if (snapshot == null || !snapshot.exists()) return; String state = snapshot.getString("state"); Long roundLong = snapshot.getLong("currentRound"); int currentRound = roundLong != null ? roundLong.intValue() : 0; @@ -422,12 +412,10 @@ public void updatePlayerScore( String sessionId, String playerId, int score, - int roundScore, FirebaseGateway.SimpleCallback callback ) { Map update = new HashMap<>(); update.put("score", score); - update.put("roundScore", roundScore); firestore.collection(SESSIONS) .document(sessionId) @@ -437,51 +425,4 @@ public void updatePlayerScore( .addOnSuccessListener(unused -> callback.onSuccess()) .addOnFailureListener(callback::onFailure); } - - public void resetSessionForNewGame( - String sessionId, - FirebaseGateway.SimpleCallback callback - ) { - // Delete all Answers first - firestore.collection(SESSIONS) - .document(sessionId) - .collection("Answers") - .get() - .addOnSuccessListener(answersSnap -> { - WriteBatch batch = firestore.batch(); - - for (DocumentSnapshot doc : answersSnap.getDocuments()) { - batch.delete(doc.getReference()); - } - - // Reset all player scores to 0 in the same batch - firestore.collection(SESSIONS) - .document(sessionId) - .collection(PLAYERS) - .get() - .addOnSuccessListener(playersSnap -> { - Map scoreReset = new HashMap<>(); - scoreReset.put("score", 0); - scoreReset.put("roundScore", 0); - for (DocumentSnapshot p : playersSnap.getDocuments()) { - batch.update(p.getReference(), scoreReset); - } - - // Reset session state + currentRound - Map sessionReset = new HashMap<>(); - sessionReset.put("state", "lobby"); - sessionReset.put("currentRound", 0); - batch.update( - firestore.collection(SESSIONS).document(sessionId), - sessionReset - ); - - batch.commit() - .addOnSuccessListener(u -> callback.onSuccess()) - .addOnFailureListener(callback::onFailure); - }) - .addOnFailureListener(callback::onFailure); - }) - .addOnFailureListener(callback::onFailure); - } } diff --git a/core/src/main/java/group07/beatbattle/BeatBattle.java b/core/src/main/java/group07/beatbattle/BeatBattle.java index 16475d4..9f2eb24 100644 --- a/core/src/main/java/group07/beatbattle/BeatBattle.java +++ b/core/src/main/java/group07/beatbattle/BeatBattle.java @@ -8,7 +8,7 @@ import group07.beatbattle.audio.AudioPlayer; import group07.beatbattle.firebase.FirebaseGateway; import group07.beatbattle.controller.LobbyController; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.ecs.Engine; import group07.beatbattle.model.GameSession; import group07.beatbattle.service.MusicService; @@ -37,7 +37,6 @@ public BeatBattle(FirebaseGateway firebaseGateway) { private String localPlayerId; private String localPlayerName; private String localSessionId; - private String localGamePin; private boolean localIsHost; public void setServices(MusicService musicService, AudioPlayer audioPlayer) { @@ -61,8 +60,6 @@ public void setLocalSession(String sessionId, boolean isHost) { this.localIsHost = isHost; } - public void setLocalGamePin(String gamePin) { this.localGamePin = gamePin; } - public String getLocalGamePin() { return localGamePin; } public String getLocalSessionId() { return localSessionId; } public boolean isLocalHost() { return localIsHost; } diff --git a/core/src/main/java/group07/beatbattle/controller/LeaderboardController.java b/core/src/main/java/group07/beatbattle/controller/LeaderboardController.java index d2e3be4..74a3607 100644 --- a/core/src/main/java/group07/beatbattle/controller/LeaderboardController.java +++ b/core/src/main/java/group07/beatbattle/controller/LeaderboardController.java @@ -7,10 +7,8 @@ import group07.beatbattle.model.GameSession; import group07.beatbattle.model.Leaderboard; import group07.beatbattle.model.LeaderboardEntry; -import group07.beatbattle.model.GameMode; import group07.beatbattle.states.GameOverState; import group07.beatbattle.states.InRoundState; -import group07.beatbattle.states.LobbyState; import group07.beatbattle.states.StartState; import group07.beatbattle.states.StateManager; @@ -95,33 +93,6 @@ public void onBackToMenu() { StateManager.getInstance().setState(new StartState(game, new LobbyController(game))); } - public void onPlayAgain() { - String sessionId = game.getLocalSessionId(); - // Reset answers, scores, and state in Firebase, then go to lobby - game.getFirebaseGateway().resetSessionForNewGame( - sessionId, - new FirebaseGateway.SimpleCallback() { - @Override public void onSuccess() { goToLobby(); } - @Override public void onFailure(Exception e) { goToLobby(); } - } - ); - } - - private void goToLobby() { - Gdx.app.postRunnable(() -> - StateManager.getInstance().setState(new LobbyState( - game, - GameMode.CREATE, - game.getLocalSessionId(), - game.getLocalGamePin(), - game.getLocalPlayerId(), - game.getLocalPlayerName(), - true, - new LobbyController(game) - )) - ); - } - public void onGameOver() { String sessionId = game.getLocalSessionId(); if (game.isLocalHost() && sessionId != null && !sessionId.isBlank()) { diff --git a/core/src/main/java/group07/beatbattle/controller/LobbyController.java b/core/src/main/java/group07/beatbattle/controller/LobbyController.java index ddbb34e..6986237 100644 --- a/core/src/main/java/group07/beatbattle/controller/LobbyController.java +++ b/core/src/main/java/group07/beatbattle/controller/LobbyController.java @@ -70,7 +70,6 @@ public void onSuccess(SessionCreationResult result) { Gdx.app.postRunnable(() -> { game.setLocalPlayer(result.getHostId(), result.getHostName()); game.setLocalSession(result.getSessionId(), true); - game.setLocalGamePin(result.getGamePin()); view.setLoadingState(false); view.setStatusMessage(""); StateManager.getInstance().setState( @@ -115,7 +114,6 @@ public void onSuccess(SessionJoinResult result) { Gdx.app.postRunnable(() -> { game.setLocalPlayer(result.getPlayerId(), result.getPlayerName()); game.setLocalSession(result.getSessionId(), false); - game.setLocalGamePin(result.getGamePin()); view.setLoadingState(false); view.setStatusMessage(""); StateManager.getInstance().setState( @@ -274,7 +272,6 @@ private void startJoinerSyncListener(String sessionId, GameSession session) { new FirebaseGateway.SessionStateListener() { @Override public void onStateChanged(String state, int currentRound) { - if ("STOPPED".equals(lastHandled[0])) return; String key = state + ":" + currentRound; if (key.equals(lastHandled[0])) return; lastHandled[0] = key; @@ -289,27 +286,6 @@ public void onStateChanged(String state, int currentRound) { LeaderboardController lc = new LeaderboardController(game, session, lb); StateManager.getInstance().setState(new GameOverState(game, lc)); }); - } else if ("lobby".equals(state)) { - // Host pressed Play Again — kill this listener and return to lobby - lastHandled[0] = "STOPPED"; - Gdx.app.postRunnable(() -> - StateManager.getInstance().setState(new LobbyState( - game, - GameMode.JOIN, - sessionId, - game.getLocalGamePin(), - game.getLocalPlayerId(), - game.getLocalPlayerName(), - false, - new LobbyController(game) - )) - ); - } else if ("deleted".equals(state)) { - // Host deleted the session — send everyone back to start - lastHandled[0] = "STOPPED"; - Gdx.app.postRunnable(() -> - StateManager.getInstance().setState(new StartState(game, new LobbyController(game))) - ); } } @@ -331,10 +307,7 @@ public void onPlayersChanged(List updated) { Gdx.app.postRunnable(() -> { for (Player u : updated) { for (Player local : session.getPlayers()) { - if (local.getId().equals(u.getId())) { - local.setScore(u.getScore()); - local.setLastRoundScore(u.getLastRoundScore()); - } + if (local.getId().equals(u.getId())) local.setScore(u.getScore()); } } Leaderboard lb = new Leaderboard(session.getPlayers()); diff --git a/core/src/main/java/group07/beatbattle/controller/RoundController.java b/core/src/main/java/group07/beatbattle/controller/RoundController.java index db2ad95..2614fc3 100644 --- a/core/src/main/java/group07/beatbattle/controller/RoundController.java +++ b/core/src/main/java/group07/beatbattle/controller/RoundController.java @@ -28,7 +28,6 @@ public class RoundController { private final Entity roundEntity; private boolean playerAnswered = false; private boolean transitioned = false; - private boolean allAnswered = false; public RoundController(BeatBattle game, Question question, GameSession session) { this.game = game; @@ -50,19 +49,6 @@ public Question getQuestion() { return question; } - /** True once the Firebase answer count has reached totalPlayers. */ - public boolean isAllAnswered() { - return allAnswered; - } - - /** Called by the view when a player's timer expires without them clicking an answer. */ - public void onPlayerTimedOut() { - if (!playerAnswered) { - playerAnswered = true; - recordAnswerInFirebase(); - } - } - public float getTimeRemaining() { TimerComponent timer = roundEntity.getComponent(TimerComponent.class); return timer != null ? timer.timeRemaining : 0f; @@ -81,7 +67,7 @@ public void onAnswerSubmitted(String answer) { Player localPlayer = findLocalPlayer(); if (localPlayer != null) { localPlayer.addScore(points); - submitScoreToFirebase(localPlayer.getId(), localPlayer.getScore(), localPlayer.getLastRoundScore()); + submitScoreToFirebase(localPlayer.getId(), localPlayer.getScore()); } playerAnswered = true; @@ -93,7 +79,7 @@ public void onRoundExpired() { if (!playerAnswered) { Player localPlayer = findLocalPlayer(); if (localPlayer != null) { - submitScoreToFirebase(localPlayer.getId(), localPlayer.getScore(), localPlayer.getLastRoundScore()); + submitScoreToFirebase(localPlayer.getId(), localPlayer.getScore()); } recordAnswerInFirebase(); // count as answered so listener is consistent } @@ -126,7 +112,7 @@ private void startAllAnsweredListener() { @Override public void onCountChanged(int count) { if (count >= totalPlayers) { - Gdx.app.postRunnable(() -> allAnswered = true); + Gdx.app.postRunnable(() -> transitionToLeaderboard()); } } @@ -170,7 +156,7 @@ private Player findLocalPlayer() { return null; } - private void submitScoreToFirebase(String playerId, int score, int roundScore) { + private void submitScoreToFirebase(String playerId, int score) { String sessionId = game.getLocalSessionId(); if (sessionId == null || sessionId.isBlank()) return; @@ -178,7 +164,6 @@ private void submitScoreToFirebase(String playerId, int score, int roundScore) { sessionId, playerId, score, - roundScore, new FirebaseGateway.SimpleCallback() { @Override public void onSuccess() {} @Override public void onFailure(Exception exception) { @@ -221,7 +206,6 @@ public void onPlayersChanged(List updatedPlayers) { for (Player local : session.getPlayers()) { if (local.getId().equals(updated.getId())) { local.setScore(updated.getScore()); - local.setLastRoundScore(updated.getLastRoundScore()); } } } diff --git a/core/src/main/java/group07/beatbattle/controller/SettingsController.java b/core/src/main/java/group07/beatbattle/controller/SettingsController.java index 0e5fde6..8e4e680 100644 --- a/core/src/main/java/group07/beatbattle/controller/SettingsController.java +++ b/core/src/main/java/group07/beatbattle/controller/SettingsController.java @@ -3,7 +3,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Preferences; import group07.beatbattle.BeatBattle; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.model.GameMode; import group07.beatbattle.states.StartState; import group07.beatbattle.states.StateManager; diff --git a/core/src/main/java/group07/beatbattle/firebase/FirebaseGateway.java b/core/src/main/java/group07/beatbattle/firebase/FirebaseGateway.java index 572c7d0..d539696 100644 --- a/core/src/main/java/group07/beatbattle/firebase/FirebaseGateway.java +++ b/core/src/main/java/group07/beatbattle/firebase/FirebaseGateway.java @@ -67,7 +67,7 @@ void deleteSession( void listenToSessionState(String sessionId, SessionStateListener listener); - void updatePlayerScore(String sessionId, String playerId, int score, int roundScore, SimpleCallback callback); + void updatePlayerScore(String sessionId, String playerId, int score, SimpleCallback callback); /** Records that a player has submitted an answer for the given round. */ void submitAnswer(String sessionId, int roundIndex, String playerId, SimpleCallback callback); @@ -75,9 +75,6 @@ void deleteSession( /** Fires with the current answer count whenever a new answer is submitted for a round. */ void listenToRoundAnswerCount(String sessionId, int roundIndex, AnswerCountCallback callback); - /** Clears Answers, resets all player scores to 0, and sets currentRound=0. Use before Play Again. */ - void resetSessionForNewGame(String sessionId, SimpleCallback callback); - // --- Callbacks --- interface GamePinExistsCallback { diff --git a/core/src/main/java/group07/beatbattle/firebase/NoOpFirebaseGateway.java b/core/src/main/java/group07/beatbattle/firebase/NoOpFirebaseGateway.java index 21f1803..aee9965 100644 --- a/core/src/main/java/group07/beatbattle/firebase/NoOpFirebaseGateway.java +++ b/core/src/main/java/group07/beatbattle/firebase/NoOpFirebaseGateway.java @@ -94,7 +94,7 @@ public void listenToSessionState(String sessionId, SessionStateListener listener } @Override - public void updatePlayerScore(String sessionId, String playerId, int score, int roundScore, SimpleCallback callback) { + public void updatePlayerScore(String sessionId, String playerId, int score, SimpleCallback callback) { callback.onFailure(new UnsupportedOperationException("Firebase is not available on this platform")); } @@ -112,9 +112,4 @@ public void submitAnswer(String sessionId, int roundIndex, String playerId, Simp public void listenToRoundAnswerCount(String sessionId, int roundIndex, AnswerCountCallback callback) { callback.onFailure(new UnsupportedOperationException("Firebase is not available on this platform")); } - - @Override - public void resetSessionForNewGame(String sessionId, SimpleCallback callback) { - callback.onFailure(new UnsupportedOperationException("Firebase is not available on this platform")); - } } diff --git a/core/src/main/java/group07/beatbattle/utils/Strings.java b/core/src/main/java/group07/beatbattle/i18n/Strings.java similarity index 94% rename from core/src/main/java/group07/beatbattle/utils/Strings.java rename to core/src/main/java/group07/beatbattle/i18n/Strings.java index be2cf9c..33534cf 100644 --- a/core/src/main/java/group07/beatbattle/utils/Strings.java +++ b/core/src/main/java/group07/beatbattle/i18n/Strings.java @@ -1,4 +1,4 @@ -package group07.beatbattle.utils; +package group07.beatbattle.i18n; import com.badlogic.gdx.Gdx; @@ -46,7 +46,6 @@ public static String leavePlayerMsg() { : "Are you sure you want to leave the session?"; } public static String gameStarting() { return no ? "Spillet starter..." : "Game starting..."; } - public static String hostLeft() { return no ? "Verten forlot sesjonen" : "Host left the session"; } public static String startGame() { return no ? "Start spill" : "Start Game"; } // --- Round --- @@ -66,7 +65,6 @@ public static String leavePlayerMsg() { public static String gameOver() { return no ? "SPILLET ER OVER" : "GAME OVER"; } public static String finalStandings(){ return no ? "Sluttresultater" : "Final Standings"; } public static String backToMenu() { return no ? "Tilbake til menyen" : "Back to Menu"; } - public static String playAgain() { return no ? "Spill igjen" : "Play Again"; } // --- Settings --- public static String settings() { return no ? "Innstillinger" : "Settings"; } diff --git a/core/src/main/java/group07/beatbattle/model/Player.java b/core/src/main/java/group07/beatbattle/model/Player.java index 7af6767..3df88f7 100644 --- a/core/src/main/java/group07/beatbattle/model/Player.java +++ b/core/src/main/java/group07/beatbattle/model/Player.java @@ -33,8 +33,4 @@ public void addScore(int points) { public void setScore(int score) { this.score = score; } - - public void setLastRoundScore(int roundScore) { - this.lastRoundScore = roundScore; - } } diff --git a/core/src/main/java/group07/beatbattle/ui/components/ApplyButton.java b/core/src/main/java/group07/beatbattle/ui/components/ApplyButton.java index 5c7a310..14b61b1 100644 --- a/core/src/main/java/group07/beatbattle/ui/components/ApplyButton.java +++ b/core/src/main/java/group07/beatbattle/ui/components/ApplyButton.java @@ -7,7 +7,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; public class ApplyButton extends TextButton { diff --git a/core/src/main/java/group07/beatbattle/ui/components/LanguageSelector.java b/core/src/main/java/group07/beatbattle/ui/components/LanguageSelector.java index ce5589f..7c6a53e 100644 --- a/core/src/main/java/group07/beatbattle/ui/components/LanguageSelector.java +++ b/core/src/main/java/group07/beatbattle/ui/components/LanguageSelector.java @@ -15,7 +15,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Align; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; public class LanguageSelector { diff --git a/core/src/main/java/group07/beatbattle/ui/components/RoundSelector.java b/core/src/main/java/group07/beatbattle/ui/components/RoundSelector.java index a971cb0..37945b3 100644 --- a/core/src/main/java/group07/beatbattle/ui/components/RoundSelector.java +++ b/core/src/main/java/group07/beatbattle/ui/components/RoundSelector.java @@ -15,7 +15,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Align; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; public class RoundSelector { diff --git a/core/src/main/java/group07/beatbattle/ui/components/StartGameButton.java b/core/src/main/java/group07/beatbattle/ui/components/StartGameButton.java index 8ec52c3..29dc5a5 100644 --- a/core/src/main/java/group07/beatbattle/ui/components/StartGameButton.java +++ b/core/src/main/java/group07/beatbattle/ui/components/StartGameButton.java @@ -7,7 +7,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; public class StartGameButton extends TextButton { diff --git a/core/src/main/java/group07/beatbattle/view/GameOverView.java b/core/src/main/java/group07/beatbattle/view/GameOverView.java index f578f5b..eef29cd 100644 --- a/core/src/main/java/group07/beatbattle/view/GameOverView.java +++ b/core/src/main/java/group07/beatbattle/view/GameOverView.java @@ -18,7 +18,7 @@ import group07.beatbattle.BeatBattle; import group07.beatbattle.controller.LeaderboardController; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.model.LeaderboardEntry; import group07.beatbattle.ui.components.BackButton; @@ -81,18 +81,6 @@ public GameOverView(BeatBattle game, LeaderboardController controller) { root.add().expandY().row(); - // Play Again button (host only) - if (controller.isHost()) { - BackButton playAgainButton = new BackButton(Strings.playAgain(), game.getMontserratFont()); - playAgainButton.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - controller.onPlayAgain(); - } - }); - root.add(playAgainButton).width(600f).height(130f).padBottom(20f).row(); - } - // Back to menu button BackButton backButton = new BackButton(Strings.backToMenu(), game.getMontserratFont()); backButton.addListener(new ChangeListener() { diff --git a/core/src/main/java/group07/beatbattle/view/GameRoundView.java b/core/src/main/java/group07/beatbattle/view/GameRoundView.java index 84270f5..dff9e9a 100644 --- a/core/src/main/java/group07/beatbattle/view/GameRoundView.java +++ b/core/src/main/java/group07/beatbattle/view/GameRoundView.java @@ -24,7 +24,7 @@ import group07.beatbattle.controller.RoundController; import group07.beatbattle.ecs.Engine; import group07.beatbattle.ecs.systems.AudioSystem; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.model.Question; import java.util.ArrayList; @@ -208,19 +208,16 @@ public void render(float delta) { int seconds = (int) Math.ceil(controller.getTimeRemaining()); timerLabel.setText(String.valueOf(seconds)); - // Reveal answers when player clicks, timer runs out, or all players have answered - if ((answered || controller.getTimeRemaining() <= 0 || controller.isAllAnswered()) && !revealed) { - if (!answered) { - // Player didn't click — record a timeout answer so Firebase count stays accurate - controller.onPlayerTimedOut(); - } + // Reveal answers immediately when player answers (or timer runs out) + if ((answered || controller.getTimeRemaining() <= 0) && !revealed) { revealed = true; answered = true; revealAnswers(); } - // Start transition countdown when timer expires OR all players have answered - if ((controller.getTimeRemaining() <= 0 || controller.isAllAnswered()) && revealed && game.isLocalHost()) { + // Only start the transition countdown once the timer has fully run out. + // This ensures the host waits for everyone before advancing. + if (controller.getTimeRemaining() <= 0 && revealed && game.isLocalHost()) { resultDelay -= delta; if (resultDelay <= 0) { controller.onRoundExpired(); diff --git a/core/src/main/java/group07/beatbattle/view/JoinCreateView.java b/core/src/main/java/group07/beatbattle/view/JoinCreateView.java index 460297a..15c480e 100644 --- a/core/src/main/java/group07/beatbattle/view/JoinCreateView.java +++ b/core/src/main/java/group07/beatbattle/view/JoinCreateView.java @@ -14,8 +14,9 @@ import group07.beatbattle.BeatBattle; import group07.beatbattle.controller.LobbyController; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.model.GameMode; +import group07.beatbattle.model.SessionCreationResult; import group07.beatbattle.model.services.LobbyService; import group07.beatbattle.ui.components.BackButton; import group07.beatbattle.ui.components.JoinCreateButton; @@ -156,7 +157,6 @@ private Label createTitleLabel() { private TextField createPlayerNameField() { TextField textField = new TextField("", InputFieldStyles.createDefault(game.getMontserratFont())); textField.setMessageText(Strings.enterName()); - textField.setMaxLength(12); return textField; } diff --git a/core/src/main/java/group07/beatbattle/view/LeaderboardView.java b/core/src/main/java/group07/beatbattle/view/LeaderboardView.java index 878a2b9..adc3e6f 100644 --- a/core/src/main/java/group07/beatbattle/view/LeaderboardView.java +++ b/core/src/main/java/group07/beatbattle/view/LeaderboardView.java @@ -16,13 +16,14 @@ import group07.beatbattle.BeatBattle; import group07.beatbattle.controller.LeaderboardController; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.model.LeaderboardEntry; import group07.beatbattle.ui.components.BackButton; +import group07.beatbattle.ui.components.JoinCreateButton; public class LeaderboardView extends ScreenAdapter { - private static final float AUTO_ADVANCE_DELAY = 5f; + private static final float AUTO_ADVANCE_DELAY = 3f; private final BeatBattle game; private final LeaderboardController controller; @@ -71,21 +72,24 @@ public LeaderboardView(BeatBattle game, LeaderboardController controller) { Table header = new Table(); header.add(styledLabel("#", Color.LIGHT_GRAY)).width(80f).left(); header.add(styledLabel(Strings.playerCol(), Color.LIGHT_GRAY)).expandX().left(); - header.add(styledLabel(Strings.scoreCol(), Color.LIGHT_GRAY)).width(160f).right(); - header.add(new Label("", subtitleStyle())).width(120f); - root.add(header).fillX().padBottom(16f).row(); + header.add(styledLabel(Strings.scoreCol(), Color.LIGHT_GRAY)).width(200f).right(); + root.add(header).fillX().padBottom(20f).row(); - // --- All players --- - String localId = game.getLocalPlayerId(); + // --- Top 3 rows --- java.util.List entries = controller.getLeaderboard().getEntries(); + int topCount = Math.min(3, entries.size()); + for (int i = 0; i < topCount; i++) { + root.add(buildPlayerRow(entries.get(i))).fillX().padBottom(16f).row(); + } - for (LeaderboardEntry entry : entries) { - boolean isLocal = entry.getPlayerId() != null && entry.getPlayerId().equals(localId); - root.add(buildPlayerRow(entry, isLocal)).expandX().fillX().padBottom(24f).row(); + // --- Local player row (if outside top 3) --- + LeaderboardEntry local = controller.getLocalPlayerEntry(); + if (local != null && local.getRank() > 3) { + root.add(styledLabel("· · ·", Color.DARK_GRAY)).padTop(8f).padBottom(8f).row(); + root.add(buildPlayerRow(local)).fillX().padBottom(16f).row(); } - // spacer to push countdown/buttons to the bottom - root.add(new com.badlogic.gdx.scenes.scene2d.ui.Label("", subtitleStyle())).expandY().row(); + root.add().expandY().row(); // --- Countdown label (only shown to host) --- String countdownPrefix = controller.hasMoreRounds() ? Strings.nextRoundIn() : Strings.finalResultsIn(); @@ -146,24 +150,19 @@ public void dispose() { logoTexture.dispose(); } - private Table buildPlayerRow(LeaderboardEntry entry, boolean isLocal) { - Color nameColor = isLocal ? new Color(0.4f, 1f, 0.5f, 1f) : Color.WHITE; - + private Table buildPlayerRow(LeaderboardEntry entry) { Table row = new Table(); - - // Rank - row.add(styledLabel(entry.getRank() + ".", nameColor)).width(80f).left().top(); - - // Player name - row.add(styledLabel(entry.getPlayerName(), nameColor)).expandX().left().top(); - - // Score: right-aligned total, then gain label with fixed width - Color gainColor = entry.getRoundScore() > 0 - ? new Color(0.4f, 1f, 0.5f, 1f) - : Color.GRAY; - String gainText = "+" + entry.getRoundScore(); - row.add(styledLabel(String.valueOf(entry.getScore()), Color.YELLOW)).width(160f).right().top(); - row.add(styledSmallLabel(gainText, gainColor)).width(120f).left().padLeft(8f).top(); + row.add(styledLabel(entry.getRank() + ".", Color.WHITE)).width(80f).left(); + row.add(styledLabel(entry.getPlayerName(), Color.WHITE)).expandX().left(); + + Table scoreCell = new Table(); + scoreCell.add(styledLabel(String.valueOf(entry.getScore()), Color.YELLOW)).right(); + if (entry.getRoundScore() > 0) { + scoreCell.add(styledLabel(" +" + entry.getRoundScore(), new Color(0.4f, 1f, 0.5f, 1f))).right().padLeft(12f); + } else { + scoreCell.add(styledLabel(" +0", Color.GRAY)).right().padLeft(12f); + } + row.add(scoreCell).width(280f).right(); return row; } @@ -174,12 +173,6 @@ private Label styledLabel(String text, Color color) { return new Label(text, style); } - private Label styledSmallLabel(String text, Color color) { - Label label = styledLabel(text, color); - label.setFontScale(0.75f); - return label; - } - private Label.LabelStyle titleStyle() { Label.LabelStyle style = new Label.LabelStyle(); style.font = game.getOrbitronFont(); diff --git a/core/src/main/java/group07/beatbattle/view/LobbyView.java b/core/src/main/java/group07/beatbattle/view/LobbyView.java index a054830..d00b23b 100644 --- a/core/src/main/java/group07/beatbattle/view/LobbyView.java +++ b/core/src/main/java/group07/beatbattle/view/LobbyView.java @@ -21,9 +21,7 @@ import group07.beatbattle.BeatBattle; import group07.beatbattle.controller.LobbyController; -import group07.beatbattle.states.StartState; -import group07.beatbattle.states.StateManager; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.firebase.FirebaseGateway; import group07.beatbattle.model.GameMode; import group07.beatbattle.model.Player; @@ -143,14 +141,7 @@ private void startListeningToSessionState() { new FirebaseGateway.SessionStateListener() { @Override public void onStateChanged(String state, int currentRound) { - if ("deleted".equals(state) && !leavingLobby) { - // Host deleted the session — kick all joiners back to start - Gdx.app.postRunnable(() -> - StateManager.getInstance().setState( - new StartState(game, new LobbyController(game)) - ) - ); - } else if ("in_round".equals(state) && !gameStarted && !leavingLobby) { + if ("in_round".equals(state) && !gameStarted && !leavingLobby) { gameStarted = true; setStatusMessage(Strings.gameStarting()); game.getFirebaseGateway().getQuestions( @@ -292,18 +283,26 @@ private Table createPartyBox(int boxWidth, int boxHeight) { private void updatePlayersGrid(List players) { playersGrid.clear(); + float cellWidth = 260f; float cellHeight = 60f; if (players == null || players.isEmpty()) { playersGrid.add(createPlayerLabel(Strings.noPlayers())) - .expandX().fillX().height(cellHeight).pad(15); + .width(cellWidth).height(cellHeight).pad(15); return; } - for (Player player : players) { + int columnCount = 2; + for (int i = 0; i < players.size(); i++) { + Player player = players.get(i); String displayName = player.getName() + (player.isHost() ? " [H]" : ""); + playersGrid.add(createPlayerLabel(displayName)) - .expandX().fillX().height(cellHeight).padBottom(10).row(); + .width(cellWidth).height(cellHeight).pad(15); + + if ((i + 1) % columnCount == 0) { + playersGrid.row(); + } } } diff --git a/core/src/main/java/group07/beatbattle/view/SettingsView.java b/core/src/main/java/group07/beatbattle/view/SettingsView.java index 644a41d..c810881 100644 --- a/core/src/main/java/group07/beatbattle/view/SettingsView.java +++ b/core/src/main/java/group07/beatbattle/view/SettingsView.java @@ -12,7 +12,7 @@ import group07.beatbattle.BeatBattle; import group07.beatbattle.controller.SettingsController; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.model.GameMode; import group07.beatbattle.ui.components.BackButton; import group07.beatbattle.ui.components.ApplyButton; diff --git a/core/src/main/java/group07/beatbattle/view/StartView.java b/core/src/main/java/group07/beatbattle/view/StartView.java index 4fe9419..719818a 100644 --- a/core/src/main/java/group07/beatbattle/view/StartView.java +++ b/core/src/main/java/group07/beatbattle/view/StartView.java @@ -13,7 +13,7 @@ import com.badlogic.gdx.utils.Scaling; import group07.beatbattle.BeatBattle; import group07.beatbattle.controller.LobbyController; -import group07.beatbattle.utils.Strings; +import group07.beatbattle.i18n.Strings; import group07.beatbattle.ui.components.JoinCreateButton; import group07.beatbattle.ui.components.SettingsButton;