From 1bf3f0032274dc3220059f3efdfae3f65a9a1462 Mon Sep 17 00:00:00 2001 From: ramollia <@> Date: Mon, 6 Oct 2025 21:46:38 +0200 Subject: [PATCH] add: win screen --- app/src/main/java/org/toop/app/App.java | 47 ++++++++++------- .../toop/app/layer/layers/ConnectedLayer.java | 5 +- .../app/layer/layers/MultiplayerLayer.java | 16 +++--- .../layer/layers/game/GameFinishedPopup.java | 51 +++++++++++++++++++ .../app/layer/layers/game/TicTacToeLayer.java | 22 ++++++-- .../localization/localization_en.properties | 5 ++ 6 files changed, 116 insertions(+), 30 deletions(-) create mode 100644 app/src/main/java/org/toop/app/layer/layers/game/GameFinishedPopup.java diff --git a/app/src/main/java/org/toop/app/App.java b/app/src/main/java/org/toop/app/App.java index 9523452..38a4873 100644 --- a/app/src/main/java/org/toop/app/App.java +++ b/app/src/main/java/org/toop/app/App.java @@ -1,5 +1,6 @@ package org.toop.app; +import javafx.application.Platform; import org.toop.app.layer.Layer; import org.toop.app.layer.layers.MainLayer; import org.toop.app.layer.layers.QuitPopup; @@ -73,39 +74,49 @@ public final class App extends Application { } public static void activate(Layer layer) { - popAll(); - push(layer); + Platform.runLater(() -> { + popAll(); + push(layer); + }); } public static void push(Layer layer) { - root.getChildren().addLast(layer.getLayer()); - stack.push(layer); + Platform.runLater(() -> { + root.getChildren().addLast(layer.getLayer()); + stack.push(layer); + }); } public static void pop() { - root.getChildren().removeLast(); - stack.pop(); + Platform.runLater(() -> { + root.getChildren().removeLast(); + stack.pop(); - isQuitting = false; + isQuitting = false; + }); } public static void popAll() { - final int childrenCount = root.getChildren().size(); + Platform.runLater(() -> { + final int childrenCount = root.getChildren().size(); - for (int i = 0; i < childrenCount; i++) { - try { - root.getChildren().removeLast(); - } catch (Exception e) { - IO.println(e); - } - } + for (int i = 0; i < childrenCount; i++) { + try { + root.getChildren().removeLast(); + } catch (Exception e) { + IO.println(e); + } + } - stack.removeAllElements(); + stack.removeAllElements(); + }); } public static void quitPopup() { - push(new QuitPopup()); - isQuitting = true; + Platform.runLater(() -> { + push(new QuitPopup()); + isQuitting = true; + }); } public static void quit() { diff --git a/app/src/main/java/org/toop/app/layer/layers/ConnectedLayer.java b/app/src/main/java/org/toop/app/layer/layers/ConnectedLayer.java index 20fd7c5..249ee00 100644 --- a/app/src/main/java/org/toop/app/layer/layers/ConnectedLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/ConnectedLayer.java @@ -1,5 +1,6 @@ package org.toop.app.layer.layers; +import org.toop.app.GameInformation; import org.toop.app.layer.Layer; import org.toop.framework.eventbus.EventFlow; import org.toop.framework.networking.events.NetworkEvents; @@ -14,9 +15,9 @@ public final class ConnectedLayer extends Layer { String user; List onlinePlayers = new CopyOnWriteArrayList<>(); - public ConnectedLayer(long clientId, String user) { - super("multiplayer.css"); + super("primary-bg"); + this.clientId = clientId; this.user = user; reload(); diff --git a/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java b/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java index d02800c..db934e2 100644 --- a/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java @@ -1,5 +1,6 @@ package org.toop.app.layer.layers; +import javafx.application.Platform; import javafx.geometry.Pos; import javafx.scene.Node; import org.toop.app.App; @@ -10,6 +11,8 @@ import org.toop.app.layer.NodeBuilder; import org.toop.app.layer.containers.HorizontalContainer; import org.toop.app.layer.containers.VerticalContainer; import org.toop.app.layer.layers.game.TicTacToeLayer; +import org.toop.framework.eventbus.EventFlow; +import org.toop.framework.networking.events.NetworkEvents; import org.toop.local.AppContext; import java.time.LocalDateTime; @@ -128,12 +131,13 @@ public final class MultiplayerLayer extends Layer { new int[]{computer1Difficulty, computer2Difficulty}, isConnectionLocal, serverIP, serverPort))); } else { - App.activate(new TicTacToeLayer(new GameInformation( - new String[]{player1Name, player2Name}, - new boolean[]{isPlayer1Human, isPlayer2Human}, - new int[]{computer1Difficulty, computer2Difficulty}, - isConnectionLocal, serverIP, serverPort))); - + new EventFlow() + .addPostEvent(NetworkEvents.StartClient.class, serverIP, Integer.parseInt(serverPort)) + .onResponse(NetworkEvents.StartClientResponse.class, + e -> Platform.runLater( + () -> App.activate(new ConnectedLayer(e.clientId(), player1Name)) + )) + .postEvent(); } }); diff --git a/app/src/main/java/org/toop/app/layer/layers/game/GameFinishedPopup.java b/app/src/main/java/org/toop/app/layer/layers/game/GameFinishedPopup.java new file mode 100644 index 0000000..b17f758 --- /dev/null +++ b/app/src/main/java/org/toop/app/layer/layers/game/GameFinishedPopup.java @@ -0,0 +1,51 @@ +package org.toop.app.layer.layers.game; + +import javafx.geometry.Pos; +import org.toop.app.App; +import org.toop.app.layer.Container; +import org.toop.app.layer.NodeBuilder; +import org.toop.app.layer.Popup; +import org.toop.app.layer.containers.VerticalContainer; +import org.toop.app.layer.layers.MainLayer; +import org.toop.local.AppContext; + +public class GameFinishedPopup extends Popup { + private final boolean isDraw; + private final String winner; + + public GameFinishedPopup(boolean isDraw, String winner) { + super(true, "bg-popup"); + + this.isDraw = isDraw; + this.winner = winner; + + reload(); + } + + @Override + public void reload() { + popAll(); + + final Container mainContainer = new VerticalContainer(30); + + if (isDraw) { + final var drawHeader = NodeBuilder.header(AppContext.getString("drawText")); + final var goodGameText = NodeBuilder.text(AppContext.getString("goodGameText")); + + mainContainer.addNodes(drawHeader, goodGameText); + } else { + final var winHeader = NodeBuilder.header(AppContext.getString("congratulations") + ": " + winner); + final var goodGameText = NodeBuilder.text(AppContext.getString("goodGameText")); + + mainContainer.addNodes(winHeader, goodGameText); + } + + final var backToMainMenuButton = NodeBuilder.button(AppContext.getString("backToMainMenu"), () -> { + App.activate(new MainLayer()); + }); + + mainContainer.addNodes(backToMainMenuButton); + + addContainer(mainContainer, Pos.CENTER, 0, 0, 30, 30); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java b/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java index 21c0018..f98e30a 100644 --- a/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java @@ -1,11 +1,13 @@ package org.toop.app.layer.layers.game; +import javafx.scene.text.Text; import org.toop.app.App; import org.toop.app.GameInformation; import org.toop.app.canvas.TicTacToeCanvas; import org.toop.app.layer.Container; import org.toop.app.layer.Layer; import org.toop.app.layer.NodeBuilder; +import org.toop.app.layer.containers.HorizontalContainer; import org.toop.app.layer.containers.VerticalContainer; import org.toop.app.layer.layers.MainLayer; import org.toop.framework.eventbus.EventFlow; @@ -21,7 +23,6 @@ import javafx.scene.paint.Color; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.regex.Pattern; public final class TicTacToeLayer extends Layer { private TicTacToeCanvas canvas; @@ -31,6 +32,9 @@ public final class TicTacToeLayer extends Layer { private GameInformation information; + private final Text currentPlayerNameText; + private final Text currentPlayerMoveText; + private final BlockingQueue playerMoveQueue = new LinkedBlockingQueue<>(); // Todo: set these from the server @@ -40,7 +44,7 @@ public final class TicTacToeLayer extends Layer { public TicTacToeLayer(GameInformation information) { super("bg-primary"); - canvas = new TicTacToeCanvas(Color.WHITE, (App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75, (cell) -> { + canvas = new TicTacToeCanvas(Color.LIME, (App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75, (cell) -> { try { if (information.isConnectionLocal()) { if (ticTacToe.getCurrentTurn() == 0) { @@ -75,6 +79,9 @@ public final class TicTacToeLayer extends Layer { .postEvent(); } + currentPlayerNameText = NodeBuilder.header(""); + currentPlayerMoveText = NodeBuilder.header(""); + reload(); } @@ -101,7 +108,11 @@ public final class TicTacToeLayer extends Layer { final Container controlContainer = new VerticalContainer(5); controlContainer.addNodes(backButton); + final Container informationContainer = new HorizontalContainer(15); + informationContainer.addNodes(currentPlayerNameText, currentPlayerMoveText); + addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0); + addContainer(informationContainer, Pos.TOP_LEFT, 2, 2, 0, 0); addGameCanvas(canvas, Pos.CENTER, 0, 0); } @@ -115,6 +126,9 @@ public final class TicTacToeLayer extends Layer { while (running) { final int currentPlayer = ticTacToe.getCurrentTurn(); + currentPlayerNameText.setText(information.playerName()[currentPlayer]); + currentPlayerMoveText.setText(ticTacToe.getCurrentTurn() == 0? "X" : "O"); + Game.Move move = null; if (information.isPlayerHuman()[currentPlayer]) { @@ -149,9 +163,9 @@ public final class TicTacToeLayer extends Layer { if (state != Game.State.NORMAL) { if (state == Game.State.WIN) { - // Win logic + App.push(new GameFinishedPopup(false, information.playerName()[ticTacToe.getCurrentTurn()])); } else if (state == Game.State.DRAW) { - // Draw logic + App.push(new GameFinishedPopup(true, "")); } running = false; diff --git a/app/src/main/resources/assets/localization/localization_en.properties b/app/src/main/resources/assets/localization/localization_en.properties index 9931ba5..94475d4 100644 --- a/app/src/main/resources/assets/localization/localization_en.properties +++ b/app/src/main/resources/assets/localization/localization_en.properties @@ -44,6 +44,11 @@ light-hc=Light (High Contrast) layoutSize=Layout Size theme=Theme +congratulations=Congratulations +drawText=The game ended in a draw +goodGameText=Good game. Well played. +backToMainMenu=Back to main menu + arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabic) chinese=\u4e2d\u6587 (Chinese) dutch=Nederlands (Dutch)