add: win screen

This commit is contained in:
ramollia
2025-10-06 21:46:38 +02:00
parent 525adfdd04
commit 1bf3f00322
6 changed files with 116 additions and 30 deletions

View File

@@ -1,5 +1,6 @@
package org.toop.app; package org.toop.app;
import javafx.application.Platform;
import org.toop.app.layer.Layer; import org.toop.app.layer.Layer;
import org.toop.app.layer.layers.MainLayer; import org.toop.app.layer.layers.MainLayer;
import org.toop.app.layer.layers.QuitPopup; import org.toop.app.layer.layers.QuitPopup;
@@ -73,23 +74,30 @@ public final class App extends Application {
} }
public static void activate(Layer layer) { public static void activate(Layer layer) {
Platform.runLater(() -> {
popAll(); popAll();
push(layer); push(layer);
});
} }
public static void push(Layer layer) { public static void push(Layer layer) {
Platform.runLater(() -> {
root.getChildren().addLast(layer.getLayer()); root.getChildren().addLast(layer.getLayer());
stack.push(layer); stack.push(layer);
});
} }
public static void pop() { public static void pop() {
Platform.runLater(() -> {
root.getChildren().removeLast(); root.getChildren().removeLast();
stack.pop(); stack.pop();
isQuitting = false; isQuitting = false;
});
} }
public static void popAll() { public static void popAll() {
Platform.runLater(() -> {
final int childrenCount = root.getChildren().size(); final int childrenCount = root.getChildren().size();
for (int i = 0; i < childrenCount; i++) { for (int i = 0; i < childrenCount; i++) {
@@ -101,11 +109,14 @@ public final class App extends Application {
} }
stack.removeAllElements(); stack.removeAllElements();
});
} }
public static void quitPopup() { public static void quitPopup() {
Platform.runLater(() -> {
push(new QuitPopup()); push(new QuitPopup());
isQuitting = true; isQuitting = true;
});
} }
public static void quit() { public static void quit() {

View File

@@ -1,5 +1,6 @@
package org.toop.app.layer.layers; package org.toop.app.layer.layers;
import org.toop.app.GameInformation;
import org.toop.app.layer.Layer; import org.toop.app.layer.Layer;
import org.toop.framework.eventbus.EventFlow; import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents; import org.toop.framework.networking.events.NetworkEvents;
@@ -14,9 +15,9 @@ public final class ConnectedLayer extends Layer {
String user; String user;
List<String> onlinePlayers = new CopyOnWriteArrayList<>(); List<String> onlinePlayers = new CopyOnWriteArrayList<>();
public ConnectedLayer(long clientId, String user) { public ConnectedLayer(long clientId, String user) {
super("multiplayer.css"); super("primary-bg");
this.clientId = clientId; this.clientId = clientId;
this.user = user; this.user = user;
reload(); reload();

View File

@@ -1,5 +1,6 @@
package org.toop.app.layer.layers; package org.toop.app.layer.layers;
import javafx.application.Platform;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import org.toop.app.App; 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.HorizontalContainer;
import org.toop.app.layer.containers.VerticalContainer; import org.toop.app.layer.containers.VerticalContainer;
import org.toop.app.layer.layers.game.TicTacToeLayer; 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 org.toop.local.AppContext;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -128,12 +131,13 @@ public final class MultiplayerLayer extends Layer {
new int[]{computer1Difficulty, computer2Difficulty}, new int[]{computer1Difficulty, computer2Difficulty},
isConnectionLocal, serverIP, serverPort))); isConnectionLocal, serverIP, serverPort)));
} else { } else {
App.activate(new TicTacToeLayer(new GameInformation( new EventFlow()
new String[]{player1Name, player2Name}, .addPostEvent(NetworkEvents.StartClient.class, serverIP, Integer.parseInt(serverPort))
new boolean[]{isPlayer1Human, isPlayer2Human}, .onResponse(NetworkEvents.StartClientResponse.class,
new int[]{computer1Difficulty, computer2Difficulty}, e -> Platform.runLater(
isConnectionLocal, serverIP, serverPort))); () -> App.activate(new ConnectedLayer(e.clientId(), player1Name))
))
.postEvent();
} }
}); });

View File

@@ -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);
}
}

View File

@@ -1,11 +1,13 @@
package org.toop.app.layer.layers.game; package org.toop.app.layer.layers.game;
import javafx.scene.text.Text;
import org.toop.app.App; import org.toop.app.App;
import org.toop.app.GameInformation; import org.toop.app.GameInformation;
import org.toop.app.canvas.TicTacToeCanvas; import org.toop.app.canvas.TicTacToeCanvas;
import org.toop.app.layer.Container; import org.toop.app.layer.Container;
import org.toop.app.layer.Layer; import org.toop.app.layer.Layer;
import org.toop.app.layer.NodeBuilder; 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.containers.VerticalContainer;
import org.toop.app.layer.layers.MainLayer; import org.toop.app.layer.layers.MainLayer;
import org.toop.framework.eventbus.EventFlow; import org.toop.framework.eventbus.EventFlow;
@@ -21,7 +23,6 @@ import javafx.scene.paint.Color;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
public final class TicTacToeLayer extends Layer { public final class TicTacToeLayer extends Layer {
private TicTacToeCanvas canvas; private TicTacToeCanvas canvas;
@@ -31,6 +32,9 @@ public final class TicTacToeLayer extends Layer {
private GameInformation information; private GameInformation information;
private final Text currentPlayerNameText;
private final Text currentPlayerMoveText;
private final BlockingQueue<Game.Move> playerMoveQueue = new LinkedBlockingQueue<>(); private final BlockingQueue<Game.Move> playerMoveQueue = new LinkedBlockingQueue<>();
// Todo: set these from the server // Todo: set these from the server
@@ -40,7 +44,7 @@ public final class TicTacToeLayer extends Layer {
public TicTacToeLayer(GameInformation information) { public TicTacToeLayer(GameInformation information) {
super("bg-primary"); 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 { try {
if (information.isConnectionLocal()) { if (information.isConnectionLocal()) {
if (ticTacToe.getCurrentTurn() == 0) { if (ticTacToe.getCurrentTurn() == 0) {
@@ -75,6 +79,9 @@ public final class TicTacToeLayer extends Layer {
.postEvent(); .postEvent();
} }
currentPlayerNameText = NodeBuilder.header("");
currentPlayerMoveText = NodeBuilder.header("");
reload(); reload();
} }
@@ -101,7 +108,11 @@ public final class TicTacToeLayer extends Layer {
final Container controlContainer = new VerticalContainer(5); final Container controlContainer = new VerticalContainer(5);
controlContainer.addNodes(backButton); controlContainer.addNodes(backButton);
final Container informationContainer = new HorizontalContainer(15);
informationContainer.addNodes(currentPlayerNameText, currentPlayerMoveText);
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0); addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);
addContainer(informationContainer, Pos.TOP_LEFT, 2, 2, 0, 0);
addGameCanvas(canvas, Pos.CENTER, 0, 0); addGameCanvas(canvas, Pos.CENTER, 0, 0);
} }
@@ -115,6 +126,9 @@ public final class TicTacToeLayer extends Layer {
while (running) { while (running) {
final int currentPlayer = ticTacToe.getCurrentTurn(); final int currentPlayer = ticTacToe.getCurrentTurn();
currentPlayerNameText.setText(information.playerName()[currentPlayer]);
currentPlayerMoveText.setText(ticTacToe.getCurrentTurn() == 0? "X" : "O");
Game.Move move = null; Game.Move move = null;
if (information.isPlayerHuman()[currentPlayer]) { if (information.isPlayerHuman()[currentPlayer]) {
@@ -149,9 +163,9 @@ public final class TicTacToeLayer extends Layer {
if (state != Game.State.NORMAL) { if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) { if (state == Game.State.WIN) {
// Win logic App.push(new GameFinishedPopup(false, information.playerName()[ticTacToe.getCurrentTurn()]));
} else if (state == Game.State.DRAW) { } else if (state == Game.State.DRAW) {
// Draw logic App.push(new GameFinishedPopup(true, ""));
} }
running = false; running = false;

View File

@@ -44,6 +44,11 @@ light-hc=Light (High Contrast)
layoutSize=Layout Size layoutSize=Layout Size
theme=Theme 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) arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabic)
chinese=\u4e2d\u6587 (Chinese) chinese=\u4e2d\u6587 (Chinese)
dutch=Nederlands (Dutch) dutch=Nederlands (Dutch)