Skip to content

Commit

Permalink
Merge branch 'main' into 11-feature-audio-controls-muteunmute
Browse files Browse the repository at this point in the history
  • Loading branch information
mostafas authored Apr 10, 2026
2 parents 7b528d3 + 858c5ee commit 6c73b69
Show file tree
Hide file tree
Showing 15 changed files with 161 additions and 54 deletions.
3 changes: 3 additions & 0 deletions core/src/main/java/group07/beatbattle/BeatBattle.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import group07.beatbattle.audio.AudioPlayer;
import group07.beatbattle.firebase.FirebaseGateway;
import group07.beatbattle.controller.LobbyController;
import group07.beatbattle.i18n.Strings;
import group07.beatbattle.ecs.Engine;
import group07.beatbattle.model.GameSession;
import group07.beatbattle.service.MusicService;
Expand Down Expand Up @@ -72,6 +73,8 @@ public void create() {
orbitronFont = loadFont("fonts/Orbitron-Regular.ttf", 56);
oswaldFont = loadFont("fonts/Oswald-Regular.ttf", 48);

Strings.reload();

Engine engine = Engine.getInstance();
engine.addSystem(RoundSystem.getInstance());
engine.addSystem(AudioSystem.getInstance());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,12 @@ private void buildAndStartSession(String sessionId, List<Player> sessionPlayers,
Song correct = songs.get(q);

List<String> options = new ArrayList<>();
options.add(correct.getTitle() + " - " + correct.getArtist());
options.add(correct.getTitle());

int decoysAdded = 0;
for (Song decoy : decoyPool) {
if (decoysAdded >= OPTIONS_PER_Q - 1) break;
String label = decoy.getTitle() + " - " + decoy.getArtist();
String label = decoy.getTitle();
if (!options.contains(label)) {
options.add(label);
decoysAdded++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import group07.beatbattle.BeatBattle;
import group07.beatbattle.i18n.Strings;
import group07.beatbattle.model.GameMode;
import group07.beatbattle.states.StartState;
import group07.beatbattle.states.StateManager;
import group07.beatbattle.view.LobbyView;

public class SettingsController {
Expand Down Expand Up @@ -59,12 +62,17 @@ public void onApply() {
prefs.putString("language", language);
prefs.putInteger("turns", turns);
prefs.flush();
Strings.reload();
Gdx.app.log("Settings", "Settings saved");
onBack();
}

public void onBack() {
Gdx.app.log("Settings", "Back pressed");
if (sessionId == null || sessionId.isBlank()) {
StateManager.getInstance().setState(new StartState(game, new LobbyController(game)));
return;
}
game.setScreen(new LobbyView(
game,
mode,
Expand Down
74 changes: 74 additions & 0 deletions core/src/main/java/group07/beatbattle/i18n/Strings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package group07.beatbattle.i18n;

import com.badlogic.gdx.Gdx;

/**
* Simple localization helper. Call {@link #reload()} once at startup and
* again after the user changes the language in Settings.
*/
public final class Strings {

private static boolean no = false;

private Strings() {}

public static void reload() {
String lang = Gdx.app.getPreferences("settings").getString("language", "EN");
no = "NO".equalsIgnoreCase(lang);
}

// --- Start screen ---
public static String createGame() { return no ? "Lag spill" : "Create Game"; }
public static String joinGame() { return no ? "Bli med i spill" : "Join Game"; }

// --- Join/Create screen ---
public static String readyToPlay() { return no ? "Klar til å spille" : "Ready to play"; }
public static String back() { return no ? "Tilbake" : "Back"; }
public static String enterName() { return no ? "Skriv inn spillernavn" : "Enter player name"; }
public static String enterCode() { return no ? "Skriv inn spillkode" : "Enter game code"; }
public static String gameCode() { return no ? "Spillkode" : "Game Code"; }
public static String generatingCode(){ return no ? "Genererer spillkode..." : "Generating game code..."; }
public static String failedCode() { return no ? "Kunne ikke generere spillkode" : "Failed to generate game code"; }

// --- Lobby ---
public static String party() { return no ? "Lag" : "Party"; }
public static String loadingPlayers(){ return no ? "Laster spillere..." : "Loading players..."; }
public static String noPlayers() { return no ? "Ingen spillere ennå" : "No players yet"; }
public static String leaveLobby() { return no ? "Forlat lobbyen" : "Leave lobby"; }
public static String leaveHostMsg() {
return no
? "Å forlate vil slette sesjonen for alle.\nVil du fortsette?"
: "Leaving will delete the session for everyone.\nDo you want to continue?";
}
public static String leavePlayerMsg() {
return no
? "Er du sikker på at du vil forlate sesjonen?"
: "Are you sure you want to leave the session?";
}
public static String gameStarting() { return no ? "Spillet starter..." : "Game starting..."; }
public static String startGame() { return no ? "Start spill" : "Start Game"; }

// --- Round ---
public static String nowPlaying() { return no ? "Spiller nå..." : "Now Playing..."; }

// --- Leaderboard ---
public static String leaderboard() { return no ? "Ledertavle" : "Leaderboard"; }
public static String round() { return no ? "Runde" : "Round"; }
public static String playerCol() { return no ? "Spiller" : "Player"; }
public static String scoreCol() { return no ? "Poeng" : "Score"; }
public static String nextRoundIn() { return no ? "Neste runde om " : "Next round in "; }
public static String finalResultsIn(){ return no ? "Sluttresultater om " : "Final results in "; }
public static String waitingForHost(){ return no ? "Venter på vert..." : "Waiting for host..."; }
public static String leaveSession() { return no ? "Forlat sesjonen" : "Leave Session"; }

// --- Game Over ---
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"; }

// --- Settings ---
public static String settings() { return no ? "Innstillinger" : "Settings"; }
public static String apply() { return no ? "Bruk" : "Apply"; }
public static String numRounds() { return no ? "Antall runder" : "Number of rounds"; }
public static String language() { return no ? "Språk" : "Language"; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +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.i18n.Strings;

public class ApplyButton extends TextButton {

Expand Down Expand Up @@ -34,7 +35,7 @@ private static TextButtonStyle createStyle(BitmapFont font) {
}

public ApplyButton(BitmapFont font) {
super("Apply", createStyle(font));
super(Strings.apply(), createStyle(font));

pad(40f, 80f, 40f, 80f);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +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.i18n.Strings;

public class LanguageSelector {

Expand Down Expand Up @@ -46,7 +47,7 @@ public LanguageSelector(BitmapFont font, String initialLanguage) {
labelStyle.font = font;
labelStyle.fontColor = Color.LIGHT_GRAY;

Label label = new Label("Language", labelStyle);
Label label = new Label(Strings.language(), labelStyle);
label.setAlignment(Align.left);

TextButton.TextButtonStyle buttonStyle = new TextButton.TextButtonStyle();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +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.i18n.Strings;

public class RoundSelector {

Expand Down Expand Up @@ -51,7 +52,7 @@ public RoundSelector(BitmapFont font) {
labelStyle.font = font;
labelStyle.fontColor = Color.LIGHT_GRAY;

Label label = new Label("Number of rounds", labelStyle);
Label label = new Label(Strings.numRounds(), labelStyle);
label.setAlignment(Align.left);

TextButton.TextButtonStyle buttonStyle = new TextButton.TextButtonStyle();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +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.i18n.Strings;

public class StartGameButton extends TextButton {

Expand All @@ -33,7 +34,7 @@ private static TextButtonStyle createStyle(BitmapFont font) {
}

public StartGameButton(BitmapFont font) {
super("Start Game", createStyle(font));
super(Strings.startGame(), createStyle(font));

pad(40f, 80f, 40f, 80f);
}
Expand Down
13 changes: 7 additions & 6 deletions core/src/main/java/group07/beatbattle/view/GameOverView.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import group07.beatbattle.BeatBattle;
import group07.beatbattle.controller.LeaderboardController;
import group07.beatbattle.i18n.Strings;
import group07.beatbattle.model.LeaderboardEntry;
import group07.beatbattle.ui.components.BackButton;

Expand Down Expand Up @@ -55,16 +56,16 @@ public GameOverView(BeatBattle game, LeaderboardController controller) {
root.top();

// Title
root.add(makeLabel("GAME OVER", game.getOrbitronFont(), Color.WHITE))
root.add(makeLabel(Strings.gameOver(), game.getOrbitronFont(), Color.WHITE))
.padBottom(10f).row();
root.add(makeLabel("Final Standings", game.getMontserratFont(), Color.LIGHT_GRAY))
root.add(makeLabel(Strings.finalStandings(), game.getMontserratFont(), Color.LIGHT_GRAY))
.padBottom(50f).row();

// Header row
Table header = new Table();
header.add(makeLabel("#", game.getMontserratFont(), Color.LIGHT_GRAY)).width(80f).left();
header.add(makeLabel("Player", game.getMontserratFont(), Color.LIGHT_GRAY)).expandX().left();
header.add(makeLabel("Score", game.getMontserratFont(), Color.LIGHT_GRAY)).width(200f).right();
header.add(makeLabel("#", game.getMontserratFont(), Color.LIGHT_GRAY)).width(80f).left();
header.add(makeLabel(Strings.playerCol(), game.getMontserratFont(), Color.LIGHT_GRAY)).expandX().left();
header.add(makeLabel(Strings.scoreCol(), game.getMontserratFont(), Color.LIGHT_GRAY)).width(200f).right();
root.add(header).fillX().padBottom(20f).row();

// Player rows (all of them for final screen)
Expand All @@ -78,7 +79,7 @@ public GameOverView(BeatBattle game, LeaderboardController controller) {
root.add().expandY().row();

// Back to menu button
BackButton backButton = new BackButton("Back to Menu", game.getMontserratFont());
BackButton backButton = new BackButton(Strings.backToMenu(), game.getMontserratFont());
backButton.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import group07.beatbattle.controller.RoundController;
import group07.beatbattle.ecs.Engine;
import group07.beatbattle.ecs.systems.AudioSystem;
import group07.beatbattle.i18n.Strings;
import group07.beatbattle.model.Question;

import java.util.ArrayList;
Expand Down Expand Up @@ -132,7 +133,7 @@ public void changed(ChangeEvent event, Actor actor) {
infoStyle.font = game.getMontserratFont();
infoStyle.fontColor = Color.LIGHT_GRAY;

Label songLabel = new Label("Now Playing...", infoStyle);
Label songLabel = new Label(Strings.nowPlaying(), infoStyle);
songLabel.setAlignment(Align.center);
songLabel.setWrap(true);
root.add(songLabel).fillX().center().padTop(40f).padBottom(60f).row();
Expand Down
19 changes: 10 additions & 9 deletions core/src/main/java/group07/beatbattle/view/JoinCreateView.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import group07.beatbattle.BeatBattle;
import group07.beatbattle.controller.LobbyController;
import group07.beatbattle.i18n.Strings;
import group07.beatbattle.model.GameMode;
import group07.beatbattle.model.SessionCreationResult;
import group07.beatbattle.model.services.LobbyService;
Expand Down Expand Up @@ -63,8 +64,8 @@ public JoinCreateView(BeatBattle game, GameMode mode, LobbyController controller
Actor codeComponent = createCodeComponent();
statusLabel = createStatusLabel();

readyButton = new JoinCreateButton("Ready to play", game.getMontserratFont());
BackButton backButton = new BackButton("Back", game.getMontserratFont());
readyButton = new JoinCreateButton(Strings.readyToPlay(), game.getMontserratFont());
BackButton backButton = new BackButton(Strings.back(), game.getMontserratFont());
roundSelector = new RoundSelector(game.getMontserratFont());

readyButton.addListener(new ChangeListener() {
Expand Down Expand Up @@ -108,15 +109,15 @@ public void changed(ChangeEvent event, Actor actor) {
}

private void loadGamePin() {
statusLabel.setText("Generating game code...");
statusLabel.setText(Strings.generatingCode());
readyButton.setDisabled(true);

lobbyService.generateAvailableGamePin(new LobbyService.GamePinCallback() {
@Override
public void onSuccess(String gamePin) {
Gdx.app.postRunnable(() -> {
generatedGamePin = gamePin;
gameCodeLabel.setText("Game Code: " + gamePin);
gameCodeLabel.setText(Strings.gameCode() + ": " + gamePin);
statusLabel.setText("");
readyButton.setDisabled(false);
});
Expand All @@ -125,7 +126,7 @@ public void onSuccess(String gamePin) {
@Override
public void onFailure(Exception exception) {
Gdx.app.postRunnable(() -> {
statusLabel.setText("Failed to generate game code");
statusLabel.setText(Strings.failedCode());
readyButton.setDisabled(true);
});
}
Expand Down Expand Up @@ -154,13 +155,13 @@ private Label createTitleLabel() {
titleStyle.font = game.getOrbitronFont();
titleStyle.fontColor = Color.WHITE;

String titleText = mode == GameMode.CREATE ? "Create Game" : "Join Game";
String titleText = mode == GameMode.CREATE ? Strings.createGame() : Strings.joinGame();
return new Label(titleText, titleStyle);
}

private TextField createPlayerNameField() {
TextField textField = new TextField("", InputFieldStyles.createDefault(game.getMontserratFont()));
textField.setMessageText("Enter player name");
textField.setMessageText(Strings.enterName());
return textField;
}

Expand All @@ -183,13 +184,13 @@ private Label createGeneratedCodeLabel() {
textStyle.font = game.getMontserratFont();
textStyle.fontColor = Color.WHITE;

gameCodeLabel = new Label("Game Code: ----", textStyle);
gameCodeLabel = new Label(Strings.gameCode() + ": ----", textStyle);
return gameCodeLabel;
}

private TextField createCodeInputField() {
gameCodeField = new TextField("", InputFieldStyles.createDefault(game.getMontserratFont()));
gameCodeField.setMessageText("Enter game code");
gameCodeField.setMessageText(Strings.enterCode());
return gameCodeField;
}

Expand Down
17 changes: 9 additions & 8 deletions core/src/main/java/group07/beatbattle/view/LeaderboardView.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import group07.beatbattle.BeatBattle;
import group07.beatbattle.controller.LeaderboardController;
import group07.beatbattle.i18n.Strings;
import group07.beatbattle.model.LeaderboardEntry;
import group07.beatbattle.ui.components.BackButton;
import group07.beatbattle.ui.components.JoinCreateButton;
Expand Down Expand Up @@ -54,21 +55,21 @@ public LeaderboardView(BeatBattle game, LeaderboardController controller) {
root.top();

// --- Title ---
Label title = new Label("Leaderboard", titleStyle());
Label title = new Label(Strings.leaderboard(), titleStyle());
root.add(title).padBottom(20f).row();

// --- Round indicator ---
Label roundLabel = new Label(
"Round " + controller.getCurrentRound() + " / " + controller.getTotalRounds(),
Strings.round() + " " + controller.getCurrentRound() + " / " + controller.getTotalRounds(),
subtitleStyle()
);
root.add(roundLabel).padBottom(50f).row();

// --- Header row ---
Table header = new Table();
header.add(styledLabel("#", Color.LIGHT_GRAY)).width(80f).left();
header.add(styledLabel("Player", Color.LIGHT_GRAY)).expandX().left();
header.add(styledLabel("Score", Color.LIGHT_GRAY)).width(200f).right();
header.add(styledLabel(Strings.playerCol(), Color.LIGHT_GRAY)).expandX().left();
header.add(styledLabel(Strings.scoreCol(), Color.LIGHT_GRAY)).width(200f).right();
root.add(header).fillX().padBottom(20f).row();

// --- Top 3 rows ---
Expand All @@ -88,12 +89,12 @@ public LeaderboardView(BeatBattle game, LeaderboardController controller) {
root.add().expandY().row();

// --- Countdown label (only shown to host) ---
String countdownPrefix = controller.hasMoreRounds() ? "Next round in " : "Final results in ";
String initialText = controller.isHost() ? countdownPrefix + "3..." : "Waiting for host...";
String countdownPrefix = controller.hasMoreRounds() ? Strings.nextRoundIn() : Strings.finalResultsIn();
String initialText = controller.isHost() ? countdownPrefix + "3..." : Strings.waitingForHost();
countdownLabel = new Label(initialText, subtitleStyle());
root.add(countdownLabel).padBottom(30f).row();

BackButton leaveButton = new BackButton("Leave Session", game.getMontserratFont());
BackButton leaveButton = new BackButton(Strings.leaveSession(), game.getMontserratFont());
leaveButton.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
Expand All @@ -118,7 +119,7 @@ public void render(float delta) {
if (!advanced && controller.isHost()) {
timeLeft -= delta;
int secs = Math.max(0, (int) Math.ceil(timeLeft));
String prefix = controller.hasMoreRounds() ? "Next round in " : "Final results in ";
String prefix = controller.hasMoreRounds() ? Strings.nextRoundIn() : Strings.finalResultsIn();
countdownLabel.setText(prefix + secs + "...");

if (timeLeft <= 0) {
Expand Down
Loading

0 comments on commit 6c73b69

Please sign in to comment.