diff --git a/app/src/main/java/org/toop/app/game/ReversiGame.java b/app/src/main/java/org/toop/app/game/ReversiGame.java index a776e5c..18527fe 100644 --- a/app/src/main/java/org/toop/app/game/ReversiGame.java +++ b/app/src/main/java/org/toop/app/game/ReversiGame.java @@ -17,6 +17,7 @@ import javafx.scene.paint.Color; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; public final class ReversiGame { @@ -31,6 +32,8 @@ public final class ReversiGame { private final GameView view; private final ReversiCanvas canvas; + private final AtomicBoolean isRunning; + public ReversiGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer onMessage) { this.information = information; @@ -40,12 +43,18 @@ public final class ReversiGame { game = new Reversi(); ai = new ReversiAI(); + isRunning = new AtomicBoolean(true); + if (onForfeit == null || onExit == null) { view = new GameView(null, () -> { + isRunning.set(false); ViewStack.push(new LocalMultiplayerView(information)); }, null); } else { - view = new GameView(onForfeit, onExit, onMessage); + view = new GameView(onForfeit, () -> { + isRunning.set(false); + onExit.run(); + }, onMessage); } canvas = new ReversiCanvas(Color.GRAY, @@ -92,9 +101,7 @@ public final class ReversiGame { } private void localGameThread() { - boolean isRunning = true; - - while (isRunning) { + while (isRunning.get()) { final int currentTurn = game.getCurrentTurn(); final char currentValue = currentTurn == 0? 'B' : 'W'; final int nextTurn = (currentTurn + 1) % GameInformation.Type.playerCount(information.type); @@ -148,12 +155,16 @@ public final class ReversiGame { view.gameOver(false, ""); } - isRunning = false; + isRunning.set(false); } } } private void onMoveResponse(NetworkEvents.GameMoveResponse response) { + if (!isRunning.get()) { + return; + } + char playerChar; if (response.player().equalsIgnoreCase(information.players[0].name)) { @@ -182,6 +193,10 @@ public final class ReversiGame { } private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) { + if (!isRunning.get()) { + return; + } + moveQueue.clear(); int position = -1; @@ -202,6 +217,10 @@ public final class ReversiGame { } private void onReceivedMessage(NetworkEvents.ReceivedMessage msg) { + if (!isRunning.get()) { + return; + } + view.updateChat(msg.message()); } diff --git a/app/src/main/java/org/toop/app/game/TicTacToeGame.java b/app/src/main/java/org/toop/app/game/TicTacToeGame.java index 0ac764d..cddef0a 100644 --- a/app/src/main/java/org/toop/app/game/TicTacToeGame.java +++ b/app/src/main/java/org/toop/app/game/TicTacToeGame.java @@ -17,6 +17,7 @@ import javafx.scene.paint.Color; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; public final class TicTacToeGame { @@ -31,6 +32,8 @@ public final class TicTacToeGame { private final GameView view; private final TicTacToeCanvas canvas; + private AtomicBoolean isRunning; + public TicTacToeGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer onMessage) { this.information = information; @@ -40,12 +43,18 @@ public final class TicTacToeGame { game = new TicTacToe(); ai = new TicTacToeAI(); + isRunning = new AtomicBoolean(true); + if (onForfeit == null || onExit == null) { view = new GameView(null, () -> { + isRunning.set(false); ViewStack.push(new LocalMultiplayerView(information)); }, null); } else { - view = new GameView(onForfeit, onExit, onMessage); + view = new GameView(onForfeit, () -> { + isRunning.set(false); + onExit.run(); + }, onMessage); } canvas = new TicTacToeCanvas(Color.GRAY, @@ -90,9 +99,7 @@ public final class TicTacToeGame { } private void localGameThread() { - boolean isRunning = true; - - while (isRunning) { + while (isRunning.get()) { final int currentTurn = game.getCurrentTurn(); final char currentValue = currentTurn == 0? 'X' : 'O'; final int nextTurn = (currentTurn + 1) % GameInformation.Type.playerCount(information.type); @@ -151,12 +158,16 @@ public final class TicTacToeGame { view.gameOver(false, ""); } - isRunning = false; + isRunning.set(false); } } } private void onMoveResponse(NetworkEvents.GameMoveResponse response) { + if (!isRunning.get()) { + return; + } + char playerChar; if (response.player().equalsIgnoreCase(information.players[0].name)) { @@ -190,6 +201,10 @@ public final class TicTacToeGame { } private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) { + if (!isRunning.get()) { + return; + } + moveQueue.clear(); int position = -1; @@ -210,6 +225,10 @@ public final class TicTacToeGame { } private void onReceivedMessage(NetworkEvents.ReceivedMessage msg) { + if (!isRunning.get()) { + return; + } + view.updateChat(msg.message()); } diff --git a/app/src/main/java/org/toop/app/view/views/GameView.java b/app/src/main/java/org/toop/app/view/views/GameView.java index d6fe0f7..3834159 100644 --- a/app/src/main/java/org/toop/app/view/views/GameView.java +++ b/app/src/main/java/org/toop/app/view/views/GameView.java @@ -89,7 +89,10 @@ public final class GameView extends View { chatListView = new ListView(); chatInput = input(); - chatInput.setOnAction(_ -> onMessage.accept(chatInput.getText())); + chatInput.setOnAction(_ -> { + onMessage.accept(chatInput.getText()); + chatInput.setText(""); + }); } else { chatListView = null; chatInput = null; diff --git a/app/src/main/resources/assets/style/dark.css b/app/src/main/resources/assets/style/dark.css index 614c459..9cb894a 100644 --- a/app/src/main/resources/assets/style/dark.css +++ b/app/src/main/resources/assets/style/dark.css @@ -73,11 +73,6 @@ -fx-text-fill: #e0f2e9; } -.container { - -fx-background-color: linear-gradient(to bottom, #2b3a3e, #1a2224); - -fx-background-radius: 6; -} - .input { -fx-background-color: linear-gradient(to bottom, #1f3a3b, #124040); -fx-background-radius: 6; diff --git a/app/src/main/resources/assets/style/general.css b/app/src/main/resources/assets/style/general.css index 205bb3b..deeda43 100644 --- a/app/src/main/resources/assets/style/general.css +++ b/app/src/main/resources/assets/style/general.css @@ -6,9 +6,11 @@ .container, .credits-container { -fx-alignment: TOP_CENTER; + -fx-background-color: transparent; } -.fit { +.fit, +.fit .viewport { -fx-background-color: transparent; -fx-border-color: transparent; } diff --git a/app/src/main/resources/assets/style/high-contrast.css b/app/src/main/resources/assets/style/high-contrast.css index 6fa3343..244b203 100644 --- a/app/src/main/resources/assets/style/high-contrast.css +++ b/app/src/main/resources/assets/style/high-contrast.css @@ -73,11 +73,6 @@ -fx-text-fill: #f0fff0; } -.container { - -fx-background-color: linear-gradient(to bottom, #121e1c, #0c1210); - -fx-background-radius: 6; -} - .input { -fx-background-color: linear-gradient(to bottom, #15331a, #0e2b15); -fx-background-radius: 6; diff --git a/app/src/main/resources/assets/style/large.css b/app/src/main/resources/assets/style/large.css index 0678816..f57a7bd 100644 --- a/app/src/main/resources/assets/style/large.css +++ b/app/src/main/resources/assets/style/large.css @@ -23,11 +23,6 @@ -fx-spacing: 14; } -.credits-container { - -fx-alignment: CENTER; - -fx-padding: 28; -} - .current-player { -fx-font-size: 32px; } diff --git a/app/src/main/resources/assets/style/light.css b/app/src/main/resources/assets/style/light.css index 094d620..c959d0d 100644 --- a/app/src/main/resources/assets/style/light.css +++ b/app/src/main/resources/assets/style/light.css @@ -1,13 +1,13 @@ .bg-primary { - -fx-background-color: linear-gradient(to bottom, #f0f6f4, #dbe9e5); + -fx-background-color: linear-gradient(to bottom, #e8f1ef, #cfded9); } .bg-secondary { - -fx-background-color: linear-gradient(to bottom, #d0e0db, #b7cdc6); + -fx-background-color: linear-gradient(to bottom, #c3d6d1, #a9c2bb); } .bg-popup { - -fx-background-color: rgba(240, 248, 250, 0.9); + -fx-background-color: rgba(224, 240, 242, 0.95); -fx-background-radius: 8; -fx-effect: dropshadow(gaussian, #a0c4b088, 6, 0, 0, 2); } @@ -18,7 +18,7 @@ -fx-border-color: #5caf5c; -fx-cursor: hand; -fx-effect: dropshadow(gaussian, #7abf7aaa, 5, 0, 0, 2); - -fx-text-fill: #2a3a2a; + -fx-text-fill: #2e4d2e; -fx-font-weight: bold; } @@ -51,7 +51,7 @@ .combo-box .list-cell { -fx-background-color: transparent; - -fx-text-fill: #588758; + -fx-text-fill: #2e4d2e; } .combo-box .list-view { @@ -61,7 +61,7 @@ } .combo-box-popup .list-cell { - -fx-text-fill: #588758; + -fx-text-fill: #2e4d2e; } .combo-box-popup .list-cell:hover { @@ -70,19 +70,14 @@ .combo-box-popup .list-cell:selected { -fx-background-color: #7ac27a; - -fx-text-fill: #f0faf0; -} - -.container { - -fx-background-color: linear-gradient(to bottom, #e9f2ee, #cde3d9); - -fx-background-radius: 6; + -fx-text-fill: #ffffff; } .input { -fx-background-color: linear-gradient(to bottom, #e6f0ec, #c8dbcd); -fx-background-radius: 6; -fx-border-color: #5caf5c; - -fx-text-fill: #588758; + -fx-text-fill: #2e4d2e; -fx-font-weight: normal; } @@ -127,13 +122,13 @@ } .text { - -fx-fill: #588758; + -fx-fill: #2e4d2e; -fx-font-weight: normal; - -fx-text-fill: #588758; + -fx-text-fill: #2e4d2e; } .header { - -fx-fill: #aad3aa; + -fx-fill: #2b5c2b; -fx-font-weight: bold; - -fx-text-fill: #aad3aa; + -fx-text-fill: #2b5c2b; } \ No newline at end of file diff --git a/app/src/main/resources/assets/style/medium.css b/app/src/main/resources/assets/style/medium.css index 1bec5a3..94f849d 100644 --- a/app/src/main/resources/assets/style/medium.css +++ b/app/src/main/resources/assets/style/medium.css @@ -23,11 +23,6 @@ -fx-spacing: 10; } -.credits-container { - -fx-alignment: CENTER; - -fx-padding: 20; -} - .current-player { -fx-font-size: 24px; } diff --git a/app/src/main/resources/assets/style/small.css b/app/src/main/resources/assets/style/small.css index 44e8117..7b450d5 100644 --- a/app/src/main/resources/assets/style/small.css +++ b/app/src/main/resources/assets/style/small.css @@ -23,11 +23,6 @@ -fx-spacing: 6; } -.credits-container { - -fx-alignment: CENTER; - -fx-padding: 12; -} - .current-player { -fx-font-size: 16px; }