From c2b6aea71ed543985ceab8c1751186c80f8858dd Mon Sep 17 00:00:00 2001 From: lieght Date: Fri, 19 Sep 2025 00:00:25 +0200 Subject: [PATCH] MVP game client --- .idea/uiDesigner.xml | 5 +- img/background.jpg | Bin 0 -> 72574 bytes src/main/java/org/toop/Main.java | 42 ++---- .../java/org/toop/UI/BackgroundPanel.java | 21 +++ .../java/org/toop/UI/LocalGameSelector.form | 37 +++++ .../java/org/toop/UI/LocalGameSelector.java | 139 ++++++++++++++++++ .../java/org/toop/UI/LocalServerSelector.form | 39 +++++ .../java/org/toop/UI/LocalServerSelector.java | 34 +++++ ...torWindow.form => RemoteGameSelector.form} | 4 +- ...torWindow.java => RemoteGameSelector.java} | 11 +- src/main/java/org/toop/UI/Services.form | 12 ++ src/main/java/org/toop/UI/Services.java | 6 + src/main/java/org/toop/UI/UIGameBoard.form | 34 +---- src/main/java/org/toop/UI/UIGameBoard.java | 117 +++++++-------- .../backend/tictactoe/TicTacToeServer.java | 9 +- .../server/frontend/ServerConnection.java | 8 +- 16 files changed, 379 insertions(+), 139 deletions(-) create mode 100644 img/background.jpg create mode 100644 src/main/java/org/toop/UI/BackgroundPanel.java create mode 100644 src/main/java/org/toop/UI/LocalGameSelector.form create mode 100644 src/main/java/org/toop/UI/LocalGameSelector.java create mode 100644 src/main/java/org/toop/UI/LocalServerSelector.form create mode 100644 src/main/java/org/toop/UI/LocalServerSelector.java rename src/main/java/org/toop/UI/{GameSelectorWindow.form => RemoteGameSelector.form} (98%) rename src/main/java/org/toop/UI/{GameSelectorWindow.java => RemoteGameSelector.java} (93%) create mode 100644 src/main/java/org/toop/UI/Services.form create mode 100644 src/main/java/org/toop/UI/Services.java diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml index 75d7be8..3be6285 100644 --- a/.idea/uiDesigner.xml +++ b/.idea/uiDesigner.xml @@ -119,9 +119,12 @@ + + + - \ No newline at end of file diff --git a/img/background.jpg b/img/background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0e5a01f47af89a0bea32a425f5c9cde2cff26b32 GIT binary patch literal 72574 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 E*$328j{pDw literal 0 HcmV?d00001 diff --git a/src/main/java/org/toop/Main.java b/src/main/java/org/toop/Main.java index e7866b3..01bed37 100644 --- a/src/main/java/org/toop/Main.java +++ b/src/main/java/org/toop/Main.java @@ -1,7 +1,6 @@ package org.toop; -import org.apache.logging.log4j.Level; -import org.toop.UI.GameSelectorWindow; +import org.toop.UI.LocalServerSelector; import org.toop.eventbus.EventRegistry; import org.toop.eventbus.Events; import org.toop.eventbus.GlobalEventBus; @@ -9,9 +8,7 @@ import org.toop.server.backend.ServerManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; -import org.toop.server.backend.tictactoe.TicTacToeServer; import org.toop.server.frontend.ConnectionManager; -import org.toop.server.frontend.TcpClient; import java.util.concurrent.ExecutionException; @@ -20,7 +17,8 @@ public class Main { private static boolean running = false; public static void main(String[] args) throws ExecutionException, InterruptedException { - Logging.disableAllLogs(); +// Logging.disableAllLogs(); + Logging.disableLogsForClass(EventRegistry.class); // Logging.enableLogsForClass(ServerManager.class, Level.ALL); // Logging.enableLogsForClass(TicTacToeServer.class, Level.ALL); // Logging.enableLogsForClass(TcpClient.class, Level.ALL); @@ -28,33 +26,17 @@ public class Main { initSystems(); registerEvents(); - /* - Window window = Window.setup(Window.API.GLFW, "Test", new Window.Size(1280, 720)); - Renderer renderer = Renderer.setup(Renderer.API.OPENGL); +// JFrame frame = new JFrame("Server Settings"); +// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); +// frame.setSize(800, 600); +// frame.setLocationRelativeTo(null); +// frame.setVisible(true); - if (!initEvents()) { - throw new RuntimeException("A event could not be initialized"); - } + javax.swing.SwingUtilities.invokeLater(LocalServerSelector::new); - TcpServer server = new TcpServer(5001); - Thread serverThread = new Thread(server); - serverThread.start(); - Server.start("127.0.0.1", "5001"); - // Testsss.start(""); // Used for testing server. - Window.start(""); - */ - -// ConsoleGui console = new ConsoleGui(); -// -// do { -// console.print(); -// } while (console.next()); -// -// console.print(); - - new Thread(() -> { - GameSelectorWindow gameSelectorWindow = new GameSelectorWindow(); - }).start(); +// new Thread(() -> { +// LocalServerSelector window = new LocalServerSelector(); +// }).start(); } diff --git a/src/main/java/org/toop/UI/BackgroundPanel.java b/src/main/java/org/toop/UI/BackgroundPanel.java new file mode 100644 index 0000000..4bd1caf --- /dev/null +++ b/src/main/java/org/toop/UI/BackgroundPanel.java @@ -0,0 +1,21 @@ +package org.toop.UI; + +import javax.swing.*; +import java.awt.*; + +public class BackgroundPanel extends JPanel { + private Image backgroundImage; + + public void setBackgroundImage(Image image) { + this.backgroundImage = image; + repaint(); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + if (backgroundImage != null) { + g.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/toop/UI/LocalGameSelector.form b/src/main/java/org/toop/UI/LocalGameSelector.form new file mode 100644 index 0000000..217c38a --- /dev/null +++ b/src/main/java/org/toop/UI/LocalGameSelector.form @@ -0,0 +1,37 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/org/toop/UI/LocalGameSelector.java b/src/main/java/org/toop/UI/LocalGameSelector.java new file mode 100644 index 0000000..f4ed81b --- /dev/null +++ b/src/main/java/org/toop/UI/LocalGameSelector.java @@ -0,0 +1,139 @@ +package org.toop.UI; + +import jdk.jfr.Event; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.toop.Main; +import org.toop.eventbus.Events; +import org.toop.eventbus.GlobalEventBus; + +import javax.swing.*; +import java.awt.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; + +public class LocalGameSelector extends JFrame { + private static final Logger logger = LogManager.getLogger(LocalGameSelector.class); + + private JPanel panel1; + private JComboBox gameSelectionComboBox; + private JButton startGame; + private JComboBox playerTypeSelectionBox; + + private JPanel cards; // CardLayout panel + private CardLayout cardLayout; + + private UIGameBoard tttBoard; + + public LocalGameSelector() { + setTitle("Local Game Selector"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(1920, 1080); + setLocationRelativeTo(null); + + // Setup CardLayout + cardLayout = new CardLayout(); + cards = new JPanel(cardLayout); + setContentPane(cards); + + // --- Main menu panel --- + panel1 = new JPanel(); + panel1.setLayout(new FlowLayout()); + gameSelectionComboBox = new JComboBox<>(); + gameSelectionComboBox.addItem("Tic Tac Toe"); + gameSelectionComboBox.addItem("Reversi"); + + playerTypeSelectionBox = new JComboBox<>(); + playerTypeSelectionBox.addItem("Player vs Player"); + playerTypeSelectionBox.addItem("Player vs AI"); + playerTypeSelectionBox.addItem("AI vs Player"); + + panel1.add(gameSelectionComboBox); + panel1.add(playerTypeSelectionBox); + + startGame = new JButton("Start Game"); + panel1.add(startGame); + + cards.add(panel1, "MainMenu"); + + // Start button action + startGame.addActionListener(e -> startGameClicked()); + + setVisible(true); + } + + private String createServer() { + CompletableFuture serverIdFuture = new CompletableFuture<>(); + GlobalEventBus.post(new Events.ServerEvents.StartServerRequest("5001", "tictactoe", serverIdFuture)); // TODO: what if 5001 is in use + try { + return serverIdFuture.get(); + } catch (Exception e) { + logger.error("Error getting server ID", e); + } + return null; + } + + private String createConnection() { + CompletableFuture connectionIdFuture = new CompletableFuture<>(); + GlobalEventBus.post(new Events.ServerEvents.StartConnectionRequest("127.0.0.1", "5001", connectionIdFuture)); // TODO: what if server couldn't be started with port. + try { + return connectionIdFuture.get(); + } catch (InterruptedException | ExecutionException e) { + logger.error("Error getting connection ID", e); + } + return null; + } + + private void startGameClicked() { + String playerTypes = (String) playerTypeSelectionBox.getSelectedItem(); + String selectedGame = (String) gameSelectionComboBox.getSelectedItem(); + + String serverId = createServer(); + String connectionId = createConnection(); + final String[] gameId = new String[1]; + + if ("Player vs AI".equalsIgnoreCase(playerTypes)) { + GlobalEventBus.post(new Events.ServerEvents.SendCommand(connectionId, "create_game", "Player", "AI")); + } else if ("AI vs Player".equalsIgnoreCase(playerTypes)) { + GlobalEventBus.post(new Events.ServerEvents.SendCommand(connectionId, "create_game", "Player", "AI")); + } else { // Player vs Player is default + GlobalEventBus.post(new Events.ServerEvents.SendCommand(connectionId, "create_game", "Player1", "Player2")); + } + + CountDownLatch latch = new CountDownLatch(1); // TODO: This is bad, fix later + + new Thread(() -> { + GlobalEventBus.subscribeAndRegister(Events.ServerEvents.ReceivedMessage.class, event -> { + logger.info(event.message()); + if (event.message().toLowerCase().startsWith("game created successfully")) { + String[] parts = event.message().split("\\|"); + String gameIdPart = parts[1]; + gameId[0] = gameIdPart.split(" ")[1]; + latch.countDown(); + } + }); + }).start(); + + try { + latch.await(); // TODO: Bad, fix later + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + GlobalEventBus.post(new Events.ServerEvents.SendCommand(connectionId, "START_GAME", gameId[0])); + + if ("Tic Tac Toe".equalsIgnoreCase(selectedGame)) { + if (tttBoard == null) { + tttBoard = new UIGameBoard("tic tac toe", connectionId, serverId, gameId[0], this); + cards.add(tttBoard.getTTTPanel(), "TicTacToe"); + } + cardLayout.show(cards, "TicTacToe"); + } + } + + public void showMainMenu() { + cardLayout.show(cards, "MainMenu"); + } +} diff --git a/src/main/java/org/toop/UI/LocalServerSelector.form b/src/main/java/org/toop/UI/LocalServerSelector.form new file mode 100644 index 0000000..be26eaf --- /dev/null +++ b/src/main/java/org/toop/UI/LocalServerSelector.form @@ -0,0 +1,39 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/org/toop/UI/LocalServerSelector.java b/src/main/java/org/toop/UI/LocalServerSelector.java new file mode 100644 index 0000000..fefbac9 --- /dev/null +++ b/src/main/java/org/toop/UI/LocalServerSelector.java @@ -0,0 +1,34 @@ +package org.toop.UI; + +import javax.swing.*; + +public class LocalServerSelector { + private JPanel panel1; + private JButton serverButton; + private JButton localButton; + private final JFrame frame; + + public LocalServerSelector() { + frame = new JFrame("Server Selector"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setContentPane(panel1); + frame.setSize(1920, 1080); + frame.setLocationRelativeTo(null); // Sets to center + frame.setVisible(true); + + serverButton.addActionListener(e -> onServerClicked()); + localButton.addActionListener(e -> onLocalClicked()); + + } + + private void onServerClicked() { + frame.dispose(); + new RemoteGameSelector(); + } + + private void onLocalClicked() { + frame.dispose(); + new LocalGameSelector(); + } + +} diff --git a/src/main/java/org/toop/UI/GameSelectorWindow.form b/src/main/java/org/toop/UI/RemoteGameSelector.form similarity index 98% rename from src/main/java/org/toop/UI/GameSelectorWindow.form rename to src/main/java/org/toop/UI/RemoteGameSelector.form index e510e3f..902cb76 100644 --- a/src/main/java/org/toop/UI/GameSelectorWindow.form +++ b/src/main/java/org/toop/UI/RemoteGameSelector.form @@ -1,9 +1,9 @@ -
+ - + diff --git a/src/main/java/org/toop/UI/GameSelectorWindow.java b/src/main/java/org/toop/UI/RemoteGameSelector.java similarity index 93% rename from src/main/java/org/toop/UI/GameSelectorWindow.java rename to src/main/java/org/toop/UI/RemoteGameSelector.java index e40b1ee..d01a52c 100644 --- a/src/main/java/org/toop/UI/GameSelectorWindow.java +++ b/src/main/java/org/toop/UI/RemoteGameSelector.java @@ -6,14 +6,13 @@ import org.toop.eventbus.GlobalEventBus; import javax.swing.*; import java.awt.event.ActionEvent; -import java.util.Locale; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -public class GameSelectorWindow extends JFrame { - private static final Logger logger = LogManager.getLogger(GameSelectorWindow.class); +public class RemoteGameSelector { + private static final Logger logger = LogManager.getLogger(RemoteGameSelector.class); private JPanel mainMenu; private JTextField nameTextField; @@ -27,7 +26,7 @@ public class GameSelectorWindow extends JFrame { private JFrame frame; private JLabel fillAllFields; - public GameSelectorWindow() { + public RemoteGameSelector() { gameSelectorBox.addItem("Tic Tac Toe"); gameSelectorBox.addItem("Reversi"); //todo get supported games from server and add to gameSelectorBox @@ -107,8 +106,8 @@ public class GameSelectorWindow extends JFrame { frame.remove(mainMenu); - UIGameBoard ttt = new UIGameBoard(gameSelectorBox.getSelectedItem().toString(),this); - frame.add(ttt.getTTTPanel()); +// UIGameBoard ttt = new UIGameBoard("tic tac toe", "test", "test",this); // TODO: Fix later +// frame.add(ttt.getTTTPanel()); // TODO: Fix later frame.revalidate(); frame.repaint(); } else { diff --git a/src/main/java/org/toop/UI/Services.form b/src/main/java/org/toop/UI/Services.form new file mode 100644 index 0000000..82187e2 --- /dev/null +++ b/src/main/java/org/toop/UI/Services.form @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/main/java/org/toop/UI/Services.java b/src/main/java/org/toop/UI/Services.java new file mode 100644 index 0000000..e1c8ae3 --- /dev/null +++ b/src/main/java/org/toop/UI/Services.java @@ -0,0 +1,6 @@ +package org.toop.UI; + +import javax.swing.*; + +public class Services { +} diff --git a/src/main/java/org/toop/UI/UIGameBoard.form b/src/main/java/org/toop/UI/UIGameBoard.form index 0d285e4..09a9ed6 100644 --- a/src/main/java/org/toop/UI/UIGameBoard.form +++ b/src/main/java/org/toop/UI/UIGameBoard.form @@ -1,6 +1,6 @@
- + @@ -10,38 +10,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/toop/UI/UIGameBoard.java b/src/main/java/org/toop/UI/UIGameBoard.java index 62b45fe..f103c53 100644 --- a/src/main/java/org/toop/UI/UIGameBoard.java +++ b/src/main/java/org/toop/UI/UIGameBoard.java @@ -1,79 +1,76 @@ package org.toop.UI; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.toop.Main; import org.toop.eventbus.Events; import org.toop.eventbus.GlobalEventBus; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; +import java.util.Objects; -public class UIGameBoard extends JFrame { - private static final Logger logger = LogManager.getLogger(UIGameBoard.class); +public class UIGameBoard { + private static final int TICTACTOE_SIZE = 3; - private final int TICTACTOE_SIZE = 3; - private final int REVERSI_SIZE = 8; - private JLabel name; - private JLabel ip; - private JLabel gameName; - private JPanel tttPanel; - private JPanel cellPanel; + private JPanel tttPanel; // Root panel for this game private JButton backToMainMenuButton; - private JButton[] buttons = new JButton[9]; private JButton[] cells; - public UIGameBoard(String game,GameSelectorWindow gameSelectorWindow) { + private String currentPlayer = "X"; - //cellPanel = new JPanel(); - JPanel gamePanel = new JPanel(); - if(game.toLowerCase().equals("tic tac toe")) { - gamePanel = createGridPanel(TICTACTOE_SIZE, TICTACTOE_SIZE); - } - if(game.toLowerCase().equals("reversi")) { - gamePanel = createGridPanel(REVERSI_SIZE, REVERSI_SIZE); + private String gameConnectionId; + private String serverId; + private String gameId; + + private LocalGameSelector parentSelector; + + public UIGameBoard(String gameType, String gameConnectionId, String serverId, String gameId, LocalGameSelector parent) { + this.parentSelector = parent; + + this .gameConnectionId = gameConnectionId; + this.serverId = serverId; + this.gameId = gameId; + + // Root panel + tttPanel = new JPanel(new BorderLayout()); + + // Back button + backToMainMenuButton = new JButton("Back to Main Menu"); + tttPanel.add(backToMainMenuButton, BorderLayout.SOUTH); + backToMainMenuButton.addActionListener(e -> + // TODO reset game and connections + parent.showMainMenu() + ); + + // Game grid + JPanel gameGrid = createGridPanel(TICTACTOE_SIZE, TICTACTOE_SIZE); + tttPanel.add(gameGrid, BorderLayout.CENTER); + } + + private JPanel createGridPanel(int sizeX, int sizeY) { + JPanel panel = new JPanel(new GridLayout(sizeX, sizeY)); + cells = new JButton[sizeX * sizeY]; + + for (int i = 0; i < sizeX * sizeY; i++) { + cells[i] = new JButton(" "); + cells[i].setFont(new Font("Arial", Font.BOLD, 100 / sizeX)); + panel.add(cells[i]); + + final int index = i; + cells[i].addActionListener((ActionEvent e) -> { + cells[index].setText(currentPlayer); + if (Objects.equals(currentPlayer, "X")) { currentPlayer = "O"; } + else { currentPlayer = "X"; } + GlobalEventBus.post(new Events.ServerEvents.SendCommand(this.gameConnectionId, + "gameid ", this.gameId, + "player ", this.currentPlayer, // TODO: Actual player names + "MOVE", "" + index)); + System.out.println("Cell clicked: " + index); + }); } - cellPanel.removeAll(); - cellPanel.add(gamePanel); - cellPanel.revalidate(); - cellPanel.repaint(); - //tttPanel.add(cellPanel); - backToMainMenuButton.addActionListener(( - ActionEvent e) -> { - gameSelectorWindow.returnToMainMenu(); - System.out.println("gothere"); - }); - } - //Set the IP, game name and name - public void setIGN(String ip, String gameName, String name) { - this.ip.setText(ip); - this.gameName.setText(gameName); - this.name.setText(name); + return panel; } + public JPanel getTTTPanel() { return tttPanel; } - //Creates a grid of buttons and adds a global event bus event on click with the index of the button. - private JPanel createGridPanel(int sizeX, int sizeY) { - JPanel cellPanel = new JPanel(new GridLayout(sizeX,sizeY)); - cells = new JButton[sizeX*sizeY]; - for(int i =0; i < sizeX*sizeY; i++){ - cells[i] = new JButton(" "); - cells[i].setPreferredSize(new Dimension(1000/sizeX,1000/sizeY)); - cells[i].setFont(new Font("Arial", Font.BOLD, 480/sizeX)); - cells[i].setFocusPainted(false); - cellPanel.add(cells[i]); - final int index = i; - cells[i].addActionListener((ActionEvent e) -> { - setCell(index,"X");//■ todo get current player - GlobalEventBus.post(new Events.ServerEvents.CellClicked(index)); - logger.info("Grid button {} was clicked.", index); - }); - } - return cellPanel; - } - public void setCell(int cell, String newValue){ - cells[cell].setText(newValue); - } -} +} \ No newline at end of file diff --git a/src/main/java/org/toop/server/backend/tictactoe/TicTacToeServer.java b/src/main/java/org/toop/server/backend/tictactoe/TicTacToeServer.java index ac49390..9685589 100644 --- a/src/main/java/org/toop/server/backend/tictactoe/TicTacToeServer.java +++ b/src/main/java/org/toop/server/backend/tictactoe/TicTacToeServer.java @@ -112,8 +112,9 @@ public class TicTacToeServer extends TcpServer { String gameId = this.newGame((String) command.arguments.getFirst(), (String) command.arguments.get(1)); this.sendQueue.offer("game created successfully|gameid " + gameId); } else if (command.command == TicTacToeServerCommand.START_GAME) { - this.runGame((String) command.arguments.getFirst()); - this.sendQueue.offer("svr game is running successfully"); + boolean success = this.runGame((String) command.arguments.getFirst()); + if (success) {this.sendQueue.offer("svr game is running successfully");} + else {this.sendQueue.offer("svr running game failed");} } else if (command.command == TicTacToeServerCommand.END_GAME) { this.endGame((String) command.arguments.getFirst()); this.sendQueue.offer("svr game ended successfully"); @@ -150,13 +151,15 @@ public class TicTacToeServer extends TcpServer { return gameId; } - public void runGame(String gameId) { + public boolean runGame(String gameId) { TicTacToe game = this.games.get(gameId); if (game != null) { game.run(); logger.info("Running game: {}, players: {}", gameId, game.getPlayers()); + return true; } else { logger.warn("Tried to run unknown game {}", gameId); + return false; } } diff --git a/src/main/java/org/toop/server/frontend/ServerConnection.java b/src/main/java/org/toop/server/frontend/ServerConnection.java index 2f8a99f..ce0ed13 100644 --- a/src/main/java/org/toop/server/frontend/ServerConnection.java +++ b/src/main/java/org/toop/server/frontend/ServerConnection.java @@ -52,10 +52,10 @@ public final class ServerConnection implements Runnable { // return; // } // TODO: DO I CARE? - if (!this.running) { - logger.warn("Server has been stopped"); - return; - } +// if (!this.running) { +// logger.warn("Server has been stopped"); +// return; +// } // TODO: Server not running String command = String.join(" ", args);