Skip to content

add settings that can change the language #41

Merged
merged 1 commit into from
Apr 10, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -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 @@ -22,6 +22,7 @@
import group07.beatbattle.BeatBattle;
import group07.beatbattle.controller.RoundController;
import group07.beatbattle.ecs.Engine;
import group07.beatbattle.i18n.Strings;
import group07.beatbattle.model.Question;

import java.util.ArrayList;
Expand Down Expand Up @@ -111,7 +112,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
Loading