Merge branch 'Development' into Widgets

This commit is contained in:
tichohidding
2025-11-27 17:19:17 +01:00
committed by GitHub
36 changed files with 551 additions and 364 deletions

View File

@@ -43,13 +43,15 @@ public final class App extends Application {
scene.getRoot();
stage.setMinWidth(1080);
stage.setMinHeight(720);
stage.setOnCloseRequest(event -> {
event.consume();
startQuit();
});
stage.setScene(scene);
stage.setResizable(false);
stage.setResizable(true);
stage.show();

View File

@@ -123,6 +123,7 @@ public final class Server {
information.players[0].name = user;
information.players[0].isHuman = false;
information.players[0].computerDifficulty = 5;
information.players[0].computerThinkTime = 1;
information.players[1].name = response.opponent();
Runnable onGameOverRunnable = isSingleGame.get()? null: this::gameOver;

View File

@@ -6,6 +6,6 @@ import java.util.function.Consumer;
public class Connect4Canvas extends GameCanvas {
public Connect4Canvas(Color color, int width, int height, Consumer<Integer> onCellClicked) {
super(color, Color.TRANSPARENT, width, height, 7, 6, 10, true, onCellClicked);
super(color, Color.TRANSPARENT, width, height, 7, 6, 10, true, onCellClicked,null);
}
}

View File

@@ -8,6 +8,7 @@ import javafx.scene.input.MouseButton;
import javafx.scene.paint.Color;
import javafx.util.Duration;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
public abstract class GameCanvas {
@@ -35,7 +36,7 @@ public abstract class GameCanvas {
protected final Cell[] cells;
protected GameCanvas(Color color, Color backgroundColor, int width, int height, int rowSize, int columnSize, int gapSize, boolean edges, Consumer<Integer> onCellClicked) {
protected GameCanvas(Color color, Color backgroundColor, int width, int height, int rowSize, int columnSize, int gapSize, boolean edges, Consumer<Integer> onCellClicked, Consumer<Integer> newCellEntered) {
canvas = new Canvas(width, height);
graphics = canvas.getGraphicsContext2D();
@@ -81,6 +82,9 @@ public abstract class GameCanvas {
}
});
render();
}
@@ -150,6 +154,21 @@ public abstract class GameCanvas {
graphics.fillOval(x, y, width, height);
}
public void drawInnerDot(Color color, int cell, boolean slightlyBigger) {
final float x = cells[cell].x() + gapSize;
final float y = cells[cell].y() + gapSize;
float multiplier = slightlyBigger?1.4f:1.5f;
final float width = (cells[cell].width() - gapSize * 2)/multiplier;
final float height = (cells[cell].height() - gapSize * 2)/multiplier;
float offset = slightlyBigger?5f:4f;
graphics.setFill(color);
graphics.fillOval(x + width/offset, y + height/offset, width, height);
}
private void drawDotScaled(Color color, int cell, double scale) {
final float cx = cells[cell].x() + gapSize;
final float cy = cells[cell].y() + gapSize;

View File

@@ -1,15 +1,68 @@
package org.toop.app.canvas;
import javafx.scene.paint.Color;
import org.toop.game.records.Move;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
public final class ReversiCanvas extends GameCanvas {
public ReversiCanvas(Color color, int width, int height, Consumer<Integer> onCellClicked) {
super(color, Color.GREEN, width, height, 8, 8, 5, true, onCellClicked);
private Move[] currentlyHighlightedMoves = null;
public ReversiCanvas(Color color, int width, int height, Consumer<Integer> onCellClicked, Consumer<Integer> newCellEntered) {
super(color, new Color(0f,0.4f,0.2f,1f), width, height, 8, 8, 5, true, onCellClicked, newCellEntered);
drawStartingDots();
final AtomicReference<Cell> lastHoveredCell = new AtomicReference<>(null);
canvas.setOnMouseMoved(event -> {
double mouseX = event.getX();
double mouseY = event.getY();
int cellId = -1;
Cell hovered = null;
for (Cell cell : cells) {
if (cell.isInside(mouseX, mouseY)) {
hovered = cell;
cellId = turnCoordsIntoCellId(mouseX, mouseY);
break;
}
}
Cell previous = lastHoveredCell.get();
if (hovered != previous) {
lastHoveredCell.set(hovered);
newCellEntered.accept(cellId);
}
});
}
public void setCurrentlyHighlightedMovesNull() {
currentlyHighlightedMoves = null;
}
public void drawHighlightDots(Move[] moves){
if (currentlyHighlightedMoves != null){
for (final Move move : currentlyHighlightedMoves){
Color color = move.value() == 'W'? Color.BLACK: Color.WHITE;
drawInnerDot(color, move.position(), true);
}
}
currentlyHighlightedMoves = moves;
if (moves != null) {
for (Move move : moves) {
Color color = move.value() == 'B' ? Color.BLACK : Color.WHITE;
drawInnerDot(color, move.position(), false);
}
}
}
private int turnCoordsIntoCellId(double x, double y) {
final int column = (int) ((x / this.width) * rowSize);
final int row = (int) ((y / this.height) * columnSize);
return column + row * rowSize;
}
public void drawStartingDots() {
drawDot(Color.BLACK, 28);
drawDot(Color.WHITE, 36);
@@ -17,7 +70,15 @@ public final class ReversiCanvas extends GameCanvas {
drawDot(Color.WHITE, 27);
}
public void drawLegalPosition(Color color, int cell) {
drawDot(new Color(color.getRed(), color.getGreen(), color.getBlue(), 0.25), cell);
public void drawLegalPosition(int cell, char player) {
Color innerColor;
if (player == 'B') {
innerColor = new Color(0.0f, 0.0f, 0.0f, 0.6f);
}
else {
innerColor = new Color(1.0f, 1.0f, 1.0f, 0.75f);
}
drawInnerDot(innerColor, cell,false);
}
}

View File

@@ -6,7 +6,7 @@ import java.util.function.Consumer;
public final class TicTacToeCanvas extends GameCanvas {
public TicTacToeCanvas(Color color, int width, int height, Consumer<Integer> onCellClicked) {
super(color, Color.TRANSPARENT, width, height, 3, 3, 30, false, onCellClicked);
super(color, Color.TRANSPARENT, width, height, 3, 3, 30, false, onCellClicked,null);
}
public void drawX(Color color, int cell) {

View File

@@ -12,7 +12,8 @@ import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.Connect4.Connect4;
import org.toop.game.Connect4.Connect4AI;
import org.toop.game.Game;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -24,7 +25,7 @@ public class Connect4Game {
private final int myTurn;
private Runnable onGameOver;
private final BlockingQueue<Game.Move> moveQueue;
private final BlockingQueue<Move> moveQueue;
private final Connect4 game;
private final Connect4AI ai;
@@ -40,7 +41,7 @@ public class Connect4Game {
this.information = information;
this.myTurn = myTurn;
this.onGameOver = onGameOver;
moveQueue = new LinkedBlockingQueue<Game.Move>();
moveQueue = new LinkedBlockingQueue<Move>();
game = new Connect4();
@@ -68,7 +69,7 @@ public class Connect4Game {
final char value = game.getCurrentTurn() == 0? 'X' : 'O';
try {
moveQueue.put(new Game.Move(cell%columnSize, value));
moveQueue.put(new Move(cell%columnSize, value));
} catch (InterruptedException _) {}
}
} else {
@@ -76,7 +77,7 @@ public class Connect4Game {
final char value = myTurn == 0? 'X' : 'O';
try {
moveQueue.put(new Game.Move(cell%columnSize, value));
moveQueue.put(new Move(cell%columnSize, value));
} catch (InterruptedException _) {}
}
}
@@ -113,14 +114,14 @@ public class Connect4Game {
currentValue,
information.players[nextTurn].name);
Game.Move move = null;
Move move = null;
if (information.players[currentTurn].isHuman) {
try {
final Game.Move wants = moveQueue.take();
final Game.Move[] legalMoves = game.getLegalMoves();
final Move wants = moveQueue.take();
final Move[] legalMoves = game.getLegalMoves();
for (final Game.Move legalMove : legalMoves) {
for (final Move legalMove : legalMoves) {
if (legalMove.position() == wants.position() &&
legalMove.value() == wants.value()) {
move = wants;
@@ -147,7 +148,7 @@ public class Connect4Game {
continue;
}
final Game.State state = game.play(move);
final GameState state = game.play(move);
updateCanvas();
/*
if (move.value() == 'X') {
@@ -156,10 +157,10 @@ public class Connect4Game {
canvas.drawO(Color.ROYALBLUE, move.position());
}
*/
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
view.gameOver(true, information.players[currentTurn].name);
} else if (state == Game.State.DRAW) {
} else if (state == GameState.DRAW) {
view.gameOver(false, "");
}
@@ -181,11 +182,11 @@ public class Connect4Game {
playerChar = myTurn == 0? 'O' : 'X';
}
final Game.Move move = new Game.Move(Integer.parseInt(response.move()), playerChar);
final Game.State state = game.play(move);
final Move move = new Move(Integer.parseInt(response.move()), playerChar);
final GameState state = game.play(move);
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
if (response.player().equalsIgnoreCase(information.players[0].name)) {
view.gameOver(true, information.players[0].name);
gameOver();
@@ -193,7 +194,7 @@ public class Connect4Game {
view.gameOver(false, information.players[1].name);
gameOver();
}
} else if (state == Game.State.DRAW) {
} else if (state == GameState.DRAW) {
view.gameOver(false, "");
gameOver();
}
@@ -232,7 +233,7 @@ public class Connect4Game {
position = moveQueue.take().position();
} catch (InterruptedException _) {}
} else {
final Game.Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
final Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
assert move != null;
position = move.position();
@@ -253,10 +254,10 @@ public class Connect4Game {
private void updateCanvas() {
canvas.clearAll();
for (int i = 0; i < game.board.length; i++) {
if (game.board[i] == 'X') {
for (int i = 0; i < game.getBoard().length; i++) {
if (game.getBoard()[i] == 'X') {
canvas.drawDot(Color.RED, i);
} else if (game.board[i] == 'O') {
} else if (game.getBoard()[i] == 'O') {
canvas.drawDot(Color.BLUE, i);
}
}

View File

@@ -8,13 +8,15 @@ import org.toop.app.widget.WidgetContainer;
import org.toop.app.widget.view.GameView;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.Game;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import org.toop.game.reversi.Reversi;
import org.toop.game.reversi.ReversiAI;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import java.awt.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -69,7 +71,7 @@ public final class ReversiGame {
final char value = game.getCurrentTurn() == 0? 'B' : 'W';
try {
moveQueue.put(new Game.Move(cell, value));
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {}
}
} else {
@@ -77,11 +79,13 @@ public final class ReversiGame {
final char value = myTurn == 0? 'B' : 'W';
try {
moveQueue.put(new Game.Move(cell, value));
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {}
}
}
});
},this::highlightCells);
primary.add(Pos.CENTER, canvas.getCanvas());
WidgetContainer.getCurrentView().transitionNext(primary);
@@ -123,14 +127,14 @@ public final class ReversiGame {
currentValue,
information.players[nextTurn].name);
Game.Move move = null;
Move move = null;
if (information.players[currentTurn].isHuman) {
try {
final Game.Move wants = moveQueue.take();
final Game.Move[] legalMoves = game.getLegalMoves();
final Move wants = moveQueue.take();
final Move[] legalMoves = game.getLegalMoves();
for (final Game.Move legalMove : legalMoves) {
for (final Move legalMove : legalMoves) {
if (legalMove.position() == wants.position() &&
legalMove.value() == wants.value()) {
move = wants;
@@ -157,13 +161,18 @@ public final class ReversiGame {
continue;
}
final Game.State state = game.play(move);
canvas.setCurrentlyHighlightedMovesNull();
final GameState state = game.play(move);
updateCanvas(true);
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
primary.gameOver(true, information.players[currentTurn].name);
} else if (state == Game.State.DRAW) {
if (state != GameState.NORMAL) {
if (state == GameState.TURN_SKIPPED){
continue;
}
int winningPLayerNumber = getPlayerNumberWithHighestScore();
if (state == GameState.WIN && winningPLayerNumber > -1) {
primary.gameOver(true, information.players[winningPLayerNumber].name);
} else if (state == GameState.DRAW || winningPLayerNumber == -1) {
primary.gameOver(false, "");
}
@@ -172,6 +181,13 @@ public final class ReversiGame {
}
}
private int getPlayerNumberWithHighestScore(){
Reversi.Score score = game.getScore();
if (score.player1Score() > score.player2Score()) return 0;
if (score.player1Score() < score.player2Score()) return 1;
return -1;
}
private void onMoveResponse(NetworkEvents.GameMoveResponse response) {
if (!isRunning.get()) {
return;
@@ -185,11 +201,11 @@ public final class ReversiGame {
playerChar = myTurn == 0? 'W' : 'B';
}
final Game.Move move = new Game.Move(Integer.parseInt(response.move()), playerChar);
final Game.State state = game.play(move);
final Move move = new Move(Integer.parseInt(response.move()), playerChar);
final GameState state = game.play(move);
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
if (response.player().equalsIgnoreCase(information.players[0].name)) {
primary.gameOver(true, information.players[0].name);
gameOver();
@@ -229,7 +245,7 @@ public final class ReversiGame {
position = moveQueue.take().position();
} catch (InterruptedException _) {}
} else {
final Game.Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
final Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
assert move != null;
position = move.position();
@@ -243,15 +259,15 @@ public final class ReversiGame {
// Todo: this is very inefficient. still very fast but if the grid is bigger it might cause issues. improve.
canvas.clearAll();
for (int i = 0; i < game.board.length; i++) {
if (game.board[i] == 'B') {
for (int i = 0; i < game.getBoard().length; i++) {
if (game.getBoard()[i] == 'B') {
canvas.drawDot(Color.BLACK, i);
} else if (game.board[i] == 'W') {
} else if (game.getBoard()[i] == 'W') {
canvas.drawDot(Color.WHITE, i);
}
}
final Game.Move[] flipped = game.getMostRecentlyFlippedPieces();
final Move[] flipped = game.getMostRecentlyFlippedPieces();
final SequentialTransition animation = new SequentialTransition();
isPaused.set(true);
@@ -260,7 +276,7 @@ public final class ReversiGame {
final Color toColor = game.getCurrentPlayer() == 'W'? Color.BLACK : Color.WHITE;
if (animate && flipped != null) {
for (final Game.Move flip : flipped) {
for (final Move flip : flipped) {
canvas.clear(flip.position());
canvas.drawDot(fromColor, flip.position());
animation.getChildren().addFirst(canvas.flipDot(fromColor, toColor, flip.position()));
@@ -270,11 +286,13 @@ public final class ReversiGame {
animation.setOnFinished(_ -> {
isPaused.set(false);
final Game.Move[] legalMoves = game.getLegalMoves();
if (information.players[game.getCurrentTurn()].isHuman) {
final Move[] legalMoves = game.getLegalMoves();
for (final Game.Move legalMove : legalMoves) {
canvas.drawLegalPosition(fromColor, legalMove.position());
}
for (final Game.Move legalMove : legalMoves) {
canvas.drawLegalPosition(legalMove.position(), game.getCurrentPlayer());
}
}
});
animation.play();
@@ -289,4 +307,27 @@ public final class ReversiGame {
currentValue,
information.players[isMe? 1 : 0].name);
}
private void highlightCells(int cellEntered) {
if (information.players[game.getCurrentTurn()].isHuman) {
Move[] legalMoves = game.getLegalMoves();
boolean isLegalMove = false;
for (Move move : legalMoves) {
if (move.position() == cellEntered){
isLegalMove = true;
break;
}
}
if (cellEntered >= 0){
Move[] moves = null;
if (isLegalMove) {
moves = game.getFlipsForPotentialMove(
new Point(cellEntered%game.getColumnSize(),cellEntered/game.getRowSize()),
game.getCurrentPlayer());
}
canvas.drawHighlightDots(moves);
}
}
}
}

View File

@@ -7,7 +7,8 @@ import org.toop.app.widget.WidgetContainer;
import org.toop.app.widget.view.GameView;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.Game;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import org.toop.game.tictactoe.TicTacToe;
import org.toop.game.tictactoe.TicTacToeAI;
@@ -39,7 +40,7 @@ public final class TicTacToeGame {
this.myTurn = myTurn;
this.onGameOver = onGameOver;
moveQueue = new LinkedBlockingQueue<Game.Move>();
moveQueue = new LinkedBlockingQueue<Move>();
game = new TicTacToe();
ai = new TicTacToeAI();
@@ -66,7 +67,7 @@ public final class TicTacToeGame {
final char value = game.getCurrentTurn() == 0? 'X' : 'O';
try {
moveQueue.put(new Game.Move(cell, value));
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {}
}
} else {
@@ -74,7 +75,7 @@ public final class TicTacToeGame {
final char value = myTurn == 0? 'X' : 'O';
try {
moveQueue.put(new Game.Move(cell, value));
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {}
}
}
@@ -109,14 +110,14 @@ public final class TicTacToeGame {
currentValue,
information.players[nextTurn].name);
Game.Move move = null;
Move move = null;
if (information.players[currentTurn].isHuman) {
try {
final Game.Move wants = moveQueue.take();
final Game.Move[] legalMoves = game.getLegalMoves();
final Move wants = moveQueue.take();
final Move[] legalMoves = game.getLegalMoves();
for (final Game.Move legalMove : legalMoves) {
for (final Move legalMove : legalMoves) {
if (legalMove.position() == wants.position() &&
legalMove.value() == wants.value()) {
move = wants;
@@ -143,7 +144,7 @@ public final class TicTacToeGame {
continue;
}
final Game.State state = game.play(move);
final GameState state = game.play(move);
if (move.value() == 'X') {
canvas.drawX(Color.INDIANRED, move.position());
@@ -176,11 +177,11 @@ public final class TicTacToeGame {
playerChar = myTurn == 0? 'O' : 'X';
}
final Game.Move move = new Game.Move(Integer.parseInt(response.move()), playerChar);
final Game.State state = game.play(move);
final Move move = new Move(Integer.parseInt(response.move()), playerChar);
final GameState state = game.play(move);
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
if (response.player().equalsIgnoreCase(information.players[0].name)) {
primary.gameOver(true, information.players[0].name);
gameOver();
@@ -188,7 +189,7 @@ public final class TicTacToeGame {
primary.gameOver(false, information.players[1].name);
gameOver();
}
} else if (state == Game.State.DRAW) {
} else if (state == GameState.DRAW) {
if(game.getLegalMoves().length == 0) { //only return draw in online multiplayer if the game is actually over.
primary.gameOver(false, "");
gameOver();
@@ -227,13 +228,8 @@ public final class TicTacToeGame {
position = moveQueue.take().position();
} catch (InterruptedException _) {}
} else {
final Game.Move move;
if (information.players[1].name.equalsIgnoreCase("pism")) {
move = ai.findWorstMove(game,9);
}else{
move = ai.findBestMove(game, information.players[0].computerDifficulty);
}
final Move move;
move = ai.findBestMove(game, information.players[0].computerDifficulty);
assert move != null;
position = move.position();
}

View File

@@ -20,6 +20,7 @@ public class SongDisplay extends VBox implements Widget {
private final Text songTitle;
private final ProgressBar progressBar;
private final Text progressText;
private boolean paused = false;
public SongDisplay() {
new EventFlow()
@@ -28,7 +29,6 @@ public class SongDisplay extends VBox implements Widget {
setAlignment(Pos.CENTER);
getStyleClass().add("song-display");
// TODO ADD GOOD SONG TITLES WITH ARTISTS DISPLAYED
songTitle = new Text("song playing");
songTitle.getStyleClass().add("song-title");
@@ -38,8 +38,6 @@ public class SongDisplay extends VBox implements Widget {
progressText = new Text("0:00/0:00");
progressText.getStyleClass().add("progress-text");
// TODO ADD BETTER CSS FOR THE SKIPBUTTON WHERE ITS AT A NICER POSITION
Button skipButton = new Button(">>");
Button pauseButton = new Button("");
Button previousButton = new Button("<<");
@@ -50,20 +48,20 @@ public class SongDisplay extends VBox implements Widget {
skipButton.setOnAction( event -> {
GlobalEventBus.post(new AudioEvents.SkipMusic());
paused = false;
pauseButton.setText(getPlayString(paused));
});
pauseButton.setOnAction(event -> {
GlobalEventBus.post(new AudioEvents.PauseMusic());
if (pauseButton.getText().equals("")) {
pauseButton.setText("");
}
else if (pauseButton.getText().equals("")) {
pauseButton.setText("");
}
paused = !paused;
pauseButton.setText(getPlayString(paused));
});
previousButton.setOnAction( event -> {
GlobalEventBus.post(new AudioEvents.PreviousMusic());
paused = false;
pauseButton.setText(getPlayString(paused));
});
HBox control = new HBox(10, previousButton, pauseButton, skipButton);
@@ -114,6 +112,14 @@ public class SongDisplay extends VBox implements Widget {
public Node getNode() {
return this;
}
private String getPlayString(boolean paused) {
if (paused) {
return "";
}
else {
return "";
}
}
}

View File

@@ -15,10 +15,12 @@ import javafx.scene.text.Text;
import java.util.function.Consumer;
public final class GameView extends View {
// TODO: This should be it's own file...
private static class GameOverView extends View {
private final boolean iWon;
private final String winner;
// TODO: Make winner generic, there is no "I won" unless you play online or against bot. Should be a generic "... won" to simplify
public GameOverView(boolean iWon, String winner) {
super(false, "bg-popup");
@@ -71,6 +73,8 @@ public final class GameView extends View {
private final Text nextPlayerHeader;
private final Text gameStateFeedback = text();
private final ListView<Text> chatListView;
private final TextField chatInput;
@@ -112,34 +116,24 @@ public final class GameView extends View {
exitButton.setText(AppContext.getString("exit"));
exitButton.setOnAction(_ -> onExit.run());
currentPlayerHeader = header("", "current-player");
currentPlayerHeader = header("", "header");
currentMoveHeader = header();
nextPlayerHeader = header();
}
@Override
public void setup() {
add(Pos.TOP_RIGHT,
fit(vboxFill(
currentPlayerHeader,
hboxFill(
separator(),
currentMoveHeader,
separator()
),
nextPlayerHeader
))
add(
Pos.TOP_CENTER,
gameStateFeedback
);
add(Pos.BOTTOM_LEFT,
vboxFill(
forfeitButton,
exitButton
)
);
vboxFill(
forfeitButton,
exitButton
)
);
if (chatListView != null) {
add(Pos.BOTTOM_RIGHT,
@@ -153,6 +147,7 @@ public final class GameView extends View {
public void nextPlayer(boolean isMe, String currentPlayer, String currentMove, String nextPlayer) {
Platform.runLater(() -> {
gameStateFeedback.setText("Waiting on " + currentPlayer + " to make their move.");
currentPlayerHeader.setText(currentPlayer);
currentMoveHeader.setText(currentMove);

View File

@@ -1,5 +1,10 @@
package org.toop.local;
import java.util.Locale;
import java.util.MissingResourceException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.framework.resource.ResourceManager;
import org.toop.framework.resource.resources.LocalizationAsset;
@@ -15,6 +20,7 @@ public class AppContext {
private static Locale locale = Locale.forLanguageTag("en");
private static final ObjectProperty<Locale> localeProperty = new SimpleObjectProperty<>(locale);
private static final Logger logger = LogManager.getLogger(AppContext.class);
public static LocalizationAsset getLocalization() {
return localization;
@@ -30,7 +36,26 @@ public class AppContext {
}
public static String getString(String key) {
return localization.getString(key, locale);
assert localization != null;
// TODO: Gebruik ResourceBundle.getBundle() zodat de fallback automatisch gaat.
// Hiervoor zou de assetManager aangepast moeten worden.
try{ // Main return
return localization.getString(key, locale);
}
catch (MissingResourceException e) {
logger.error("Missing resource key: {}, in bundle: {}. ", key, locale, e);
}
try{ // Fallback return
return localization.getString(key, localization.getFallback());
}
catch (MissingResourceException e) {
logger.error("Missing resource key: {}, in default bundle!", key, e);
}
// Default return
return "MISSING RESOURCE";
}
public static StringBinding bindToKey(String key) {