diff --git a/src/AsyncSocket.java b/src/AsyncSocket.java index 0201e4e..a5aa22e 100644 --- a/src/AsyncSocket.java +++ b/src/AsyncSocket.java @@ -1,27 +1,86 @@ import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import java.io.PrintWriter; +import java.net.InetSocketAddress; +import java.net.ServerSocket; import java.net.Socket; public class AsyncSocket { private Socket socket; private Thread checkerThread; + private Thread connectorThread; private AsyncSocketListener handler; private boolean shouldStop = false; + private String sendBuffer = ""; + private BufferedReader in; - private PrintWriter out; + private BufferedWriter out; + + public AsyncSocket(int port, AsyncSocketListener handler) { + this.setHandler(handler); + + // start server in new thread + this.connectorThread = new Thread(() -> { + try { + ServerSocket serverSocket = new ServerSocket(port); + + System.out.println("Waiting for client connection on port " + port); + + Socket socket = serverSocket.accept(); + + System.out.println("Socket connected."); + + serverSocket.close(); + + this.initSocket(socket); + + } catch (IOException e) { + e.printStackTrace(); + // TODO: proper error handling + } + }); + this.connectorThread.start(); + } + + public AsyncSocket(InetSocketAddress address, AsyncSocketListener handler) { + this.setHandler(handler); + + // start client in new thread + this.connectorThread = new Thread(() -> { + System.out.println("Connecting to " + address.toString()); + + Socket socket = new Socket(); + try { + socket.connect(address, 10); + System.out.println("Socket connected."); + + this.initSocket(socket); + + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Connection timed out"); + } + + }); + this.connectorThread.start(); + } public AsyncSocket(Socket socket, AsyncSocketListener handler) throws IOException { + this.setHandler(handler); + this.initSocket(socket); + } + + private void initSocket(Socket socket) throws IOException { + System.out.println("Initialising sockets"); this.socket = socket; this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); - this.out = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream())); - - this.handler = handler; + this.out = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream())); + this.shouldStop = false; this.checkerThread = new Thread(() -> { while (!this.shouldStop) { try { @@ -29,21 +88,38 @@ public class AsyncSocket { } catch (InterruptedException e) { e.printStackTrace(); } + + if (!this.connectorThread.isAlive()) { + try { + this.connectorThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + try { - if (!this.in.ready()) continue; - if (this.handler == null) continue; + if (!this.in.ready()) { + continue; + } + if (this.handler == null) { + continue; + } String message = this.in.readLine(); if (message.length() <= 0) continue; + message = message.strip(); + System.out.println("RECEIVED - " + message); this.handler.receive(message); } catch (IOException e) { e.printStackTrace(); } } }); + System.out.println("starting checker thread"); this.checkerThread.start(); + this.flushBuffer(); } public void setHandler(AsyncSocketListener handler) { @@ -51,21 +127,36 @@ public class AsyncSocket { } - public void send(SocketPackage socketPackage) { + public synchronized void send(SocketPackage socketPackage) { this.sendLine(socketPackage.toString()); } - public void send(String packageName) { + public synchronized void send(String packageName) { this.send(packageName, ""); } - public void send(String packageName, String packageContent) { + public synchronized void send(String packageName, String packageContent) { if (packageContent.length() > 0) { packageContent = " " + packageContent; } this.sendLine(packageName + packageContent); } - public void sendLine(String message) { - this.out.print(message + "\r\n"); + public synchronized void sendLine(String message) { + sendBuffer = sendBuffer + message + "\r\n"; + this.flushBuffer(); + } + + private synchronized void flushBuffer() { + if (!this.sendBuffer.isEmpty() && this.out != null) { + try { + this.out.write(sendBuffer); + System.out.println("SENT - " + sendBuffer); + sendBuffer = ""; + this.out.flush(); + } catch (IOException e) { + e.printStackTrace(); + // TODO: handle writing error + } + } } public void close() { @@ -73,8 +164,11 @@ public class AsyncSocket { try { this.socket.close(); + this.checkerThread.join(); } catch (IOException e) { e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); } } } \ No newline at end of file diff --git a/src/Board.java b/src/Board.java index eaf8d41..f0ca737 100644 --- a/src/Board.java +++ b/src/Board.java @@ -1,4 +1,5 @@ +import java.util.ArrayList; import java.util.List; public class Board { @@ -10,6 +11,8 @@ public class Board { public Board(int size) { this.size = size; + this.ships = new ArrayList<>(); + this.hits = new ArrayList<>(); this.createShip(size - 13); } diff --git a/src/BoardDisplay.java b/src/BoardDisplay.java index 360184d..c9760ad 100644 --- a/src/BoardDisplay.java +++ b/src/BoardDisplay.java @@ -2,14 +2,32 @@ import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +/** + * TODO Klassenbeschreibung + */ public class BoardDisplay extends JPanel { - public BoardDisplay(int gridSize, Icon buttonIcon) { - super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Splate + private JButton[][] fields; + private int gridSize; + private List ships; + /** + * Konstruktor der startLocalGame. + * TODO fertig schreiben + * @param gridSize + * @param player + */ + public BoardDisplay(int gridSize, Player player) { + super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Splate + this.fields = new JButton[gridSize][gridSize]; + this.ships = new ArrayList<>(); // Erstellung von Spielfeld for (int i = 0; i <= gridSize; i++) { for (int j = 0; j <= gridSize; j++) { + final int x = i; // Temporäre Variable + final int y = j; // Temporäre Variable if (i == 0 && j == 0) { add(new JLabel(" ")); } else if (i == 0) { @@ -28,27 +46,116 @@ public class BoardDisplay extends JPanel { field.setBackground(Color.LIGHT_GRAY); field.setOpaque(true); field.setBorderPainted(true); + fields[i - 1][j - 1] = field; + add(field); + //field.addMouseListener(new MouseAdapter() { + // @Override + //public void mouseClicked(MouseEvent e) { + // if (SwingUtilities.isRightMouseButton(e)) { + // handleFieldClick(field); + // } + // } + //@Override + //public void mouseExited(MouseEvent e) { + // field.setBackground(Color.LIGHT_GRAY); + // } + // }); + int finalI = i; + int finalJ = j; field.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - if(SwingUtilities.isRightMouseButton(e)) { - handleFieldClick(field); - } - } - - @Override - public void mouseExited(MouseEvent e) { - // field.setBackground(Color.LIGHT_GRAY); + Point o= new Point(finalI, finalJ); + System.out.println(o); + handleFieldClick(field, o,player); } }); - add(field); } } } + + // this.ships = new ArrayList(); } - private void handleFieldClick(JButton field) { - field.setBackground(Color.RED); + /** + * TODO Funktion beschreiben etc. + * @param ship + * @param o + * @param horizontal + * @param player + * @return + */ + private boolean setShip(Ship ship, Point o, boolean horizontal,Player player) { + //boolean a = true; + if (placeable(ship, ship.getPosition(), horizontal)) { + ship.setPosition(new Point(o.getX(),o.getY()),player.getBoard().getShips(),gridSize); + ship.setHorizontal(horizontal); + ships.add(ship); + List occupied = ship.getOccupiedPoints(); + for(Point p: occupied) { + fields[p.getX()][p.getY()].setBackground(Color.LIGHT_GRAY); + } + return true; + }else{ + return false; + } + } + + /*private boolean placeable(Ship ship,Point o, boolean horizontal) { + if (horizontal && (o.getX() + ship.getSize() > gridSize)) { // Fehler + return false; + } + if (!horizontal && (o.getY() + ship.getSize() > gridSize)) { + return false; + } + return true; + }*/ + + /** + * TODO Funktion beschreiben etc. + * @param ship + * @param o + * @param horizontal + * @return + */ + private boolean placeable(Ship ship, Point o, boolean horizontal) { + if (horizontal && (o.getX() + ship.getSize() > gridSize)) { + return false; + } + if (!horizontal && (o.getY() + ship.getSize() > gridSize)) { + return false; + } + + // Prüfen auf Kollision mit bestehenden Schiffen + for (Ship other : ships) { + for (Point p : other.getOccupiedPoints()) { + for (Point newP : ship.getOccupiedPoints()) { + if (p.equals(newP)) { + return false; // Überschneidung gefunden + } + } + } + } + + return true; + } + + + private void selectShip(MouseEvent e) { + Ship current = (Ship) e.getSource(); + } + + /** + * TODO Funktion beschreiben etc. + * @param field + * @param o + * @param player + */ + private void handleFieldClick(JButton field, Point o,Player player) { + // Beispiel: Setze ein Schiff bei einem Klick + if (setShip(new Ship(3, "TestShip"), o, true,player)) { + field.setBackground(Color.BLUE); // Visualisiere Schiff + } } } \ No newline at end of file diff --git a/src/GameBoard.java b/src/GameBoard.java index 32d43c3..3ed0619 100644 --- a/src/GameBoard.java +++ b/src/GameBoard.java @@ -1,10 +1,17 @@ -import javafx.scene.control.ToggleGroup; +// import javafx.scene.control.ToggleGroup; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseAdapter; +import java.util.List; +/** + * Das GameBoard dient als Panel, in dem das tatsächliche Spiel stattfindet. + * Der Benutzer kann hier seine Schiffe platzieren, das Spiel starten etc. + */ public class GameBoard extends JPanel { // Funktionshilfen //int semesterCounter = 1; //TODO: ersetzen durch param von vorpanel @@ -21,24 +28,70 @@ public class GameBoard extends JPanel { JButton backButton = new JButton(backButtonIcon); // Eigene ModulButtons - JToggleButton leftPlayerModul1 = new JToggleButton("Modul 1"); //TODO: Dynamische Namen durch abgleich mit Semester - JToggleButton leftPlayerModul2 = new JToggleButton("Modul 2"); - JToggleButton leftPlayerModul3 = new JToggleButton("Modul 3"); - JToggleButton leftPlayerModul4 = new JToggleButton("Modul 4"); - JToggleButton leftPlayerModul5 = new JToggleButton("Modul 5"); - JToggleButton leftPlayerModul6 = new JToggleButton("Modul 6"); - JToggleButton leftPlayerModul7 = new JToggleButton("Reset"); - // Gegnerische ModulButtons - JToggleButton rightPlayerModul1 = new JToggleButton("Modul 1"); - JToggleButton rightPlayerModul2 = new JToggleButton("Modul 2"); - JToggleButton rightPlayerModul3 = new JToggleButton("Modul 3"); - JToggleButton rightPlayerModul4 = new JToggleButton("Modul 4"); - JToggleButton rightPlayerModul5 = new JToggleButton("Modul 5"); - JToggleButton rightPlayerModul6 = new JToggleButton("Modul 6"); - JToggleButton rightPlayerModul7 = new JToggleButton("Bereit"); + /** + * Konstruktor von GameBoard. + * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. + * @param semesterCounter Ausgewähltes Semester + * @param p1 Erstes Spielerobjekt + * @param p2 Zweites Spielerobjekt + */ + GameBoard(MainFrame frame, int semesterCounter,Player p1, Player p2) { + JToggleButton leftPlayerModul1 = new JToggleButton("Modul 1"); //TODO: Dynamische Namen durch abgleich mit Semester + JToggleButton leftPlayerModul2 = new JToggleButton("Modul 2"); + JToggleButton leftPlayerModul3 = new JToggleButton("Modul 3"); + JToggleButton leftPlayerModul4 = new JToggleButton("Modul 4"); + JToggleButton leftPlayerModul5 = new JToggleButton("Modul 5"); + JToggleButton leftPlayerModul6 = new JToggleButton("Modul 6"); + JToggleButton leftPlayerModul7 = new JToggleButton("Reset"); - public void buildPanel(MainFrame frame, int semesterCounter) { + JToggleButton[] leftPlayerButtons=new JToggleButton[]{ + leftPlayerModul1, leftPlayerModul2, leftPlayerModul3, leftPlayerModul4, + leftPlayerModul5, leftPlayerModul6, leftPlayerModul7, + }; + + // Gegnerische ModulButtons + JToggleButton rightPlayerModul1 = new JToggleButton("Modul 1"); + JToggleButton rightPlayerModul2 = new JToggleButton("Modul 2"); + JToggleButton rightPlayerModul3 = new JToggleButton("Modul 3"); + JToggleButton rightPlayerModul4 = new JToggleButton("Modul 4"); + JToggleButton rightPlayerModul5 = new JToggleButton("Modul 5"); + JToggleButton rightPlayerModul6 = new JToggleButton("Modul 6"); + JToggleButton rightPlayerModul7 = new JToggleButton("Bereit"); + + JToggleButton[] rightlayerButtons=new JToggleButton[]{ + rightPlayerModul1, rightPlayerModul2, rightPlayerModul3, rightPlayerModul4, + rightPlayerModul5, rightPlayerModul6, rightPlayerModul7, + }; + + buildPanel(frame, semesterCounter,p1,p2,leftPlayerButtons,rightlayerButtons); + List shipsP1 =p1.getBoard().getShips(); + updateButtonLabels(shipsP1,leftPlayerButtons); + backButton.addActionListener(e -> frame.showPanel("MainMenu")); + } + + /** + * TODO Funktion beschreiben etc. + * @param ships + * @param buttons + */ + private void updateButtonLabels(List ships,JToggleButton[] buttons) { + for(int i=0;i frame.showPanel("MainMenu")); } } diff --git a/src/GameController.java b/src/GameController.java index 1c5e392..5353fdd 100644 --- a/src/GameController.java +++ b/src/GameController.java @@ -1,8 +1,5 @@ import java.io.IOException; import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -19,12 +16,12 @@ public class GameController { GameController.mainFrame = mainFrame; } - // Connection timeout for client sockets in milliseconds - public static final int CONNECTION_TIMEOUT = 10 * 1000; - public static int semesterToBoardSize(int semester) { return semester + 13; } + public static int boardSizeToSemester(int size) { + return size - 13; + } public static HashMap> supportedVersions = new HashMap<>(Map.of( "1.1.0", OnlinePlayer_1_1_0.class @@ -33,34 +30,15 @@ public class GameController { public static void startOnlineGame(Class localPlayerClass, String localPlayerName, InetSocketAddress address, int size) throws IOException { AsyncSocket clientSocket; - boolean localPlayerIsServer = address.getHostName() == null; + boolean localPlayerIsServer = address.getHostName() == null || address.getHostName().isEmpty() || address.getHostName().equals("0.0.0.0"); if (localPlayerIsServer) { // SERVER MODE + clientSocket = new AsyncSocket(address.getPort(), null); - ServerSocket serverSocket = new ServerSocket(address.getPort()); - - System.out.println("Waiting for client connection..."); - - clientSocket = new AsyncSocket(serverSocket.accept(), null); - - serverSocket.close(); } else { // CLIENT MODE - - Socket socket = new Socket(); - - try { - socket.connect(address, CONNECTION_TIMEOUT); - - clientSocket = new AsyncSocket(socket, null); - } catch (SocketTimeoutException e) { - e.printStackTrace(); - throw new RuntimeException("Connection timed out"); - } finally { - socket.close(); - } - + clientSocket = new AsyncSocket(address, null); } clientSocket.send("VERSION", "Gruppe03 " + String.join(" ", supportedVersions.keySet())); @@ -84,17 +62,24 @@ public class GameController { OnlinePlayer onlinePlayer; try { localPlayer = localPlayerClass.getDeclaredConstructor().newInstance(); - onlinePlayer = onlinePlayerClass.getDeclaredConstructor().newInstance((Integer)size, clientSocket); + onlinePlayer = onlinePlayerClass.getDeclaredConstructor(Integer.class, AsyncSocket.class).newInstance((Integer)size, clientSocket); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Unable to instantiate players"); } + localPlayer.isServer = localPlayerIsServer; onlinePlayer.isServer = !localPlayerIsServer; + + localPlayer.setName(localPlayerName); - startGameWithInstancedPlayers(localPlayer, onlinePlayer); + localPlayer.setEnemy(onlinePlayer); + onlinePlayer.setEnemy(localPlayer); + onlinePlayer.sendIAM(); + + // Start game only after IAM Package was exchanged } else { throw new RuntimeException("Unexpected Package received before game initialisation"); } @@ -178,12 +163,14 @@ public class GameController { localPlayer.createBoard(size); aiPlayer.createBoard(size); - startGameWithInstancedPlayers(localPlayer, aiPlayer); + localPlayer.setEnemy(aiPlayer); + aiPlayer.setEnemy(localPlayer); + + startGameWithInstancedPlayers(localPlayer, aiPlayer, size); } - private static void startGameWithInstancedPlayers(LocalPlayer p1, Player p2) { - p1.setEnemy(p2); - p2.setEnemy(p1); + public static void startGameWithInstancedPlayers(LocalPlayer p1, Player p2, int boardSize) { + mainFrame.showPanelSLG("GameBoard", boardSizeToSemester(boardSize), p1, p2); // TODO: frontend configuration } diff --git a/src/JoinGame.java b/src/JoinGame.java index 3251d2d..76ad2c7 100644 --- a/src/JoinGame.java +++ b/src/JoinGame.java @@ -2,35 +2,53 @@ import java.awt.*; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.IOException; +import java.net.InetSocketAddress; -/* -TODO: evtl an Lucas: die "JoinGame" muss noch informationen erhalten, welche Spieler erstellt wurden und welches Semester -Also die startMultiplayerGame muss JoinGame mit parametern für (HumanPlayer/AiEasy/AiNormal/AiHard, Semesteranzahl, Spielername) (3 Parameter) erhalten - +/** + * Das JoinGame Panel dient zum setzten des Ports/IP-Adresse. + * Anschließend kann das Verbinden Panel gezeigt werden. */ - - public class JoinGame extends JPanel { + // Grafiken ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png"); + // Labels JLabel spielBeitretenLabel; JLabel ipLabel = new JLabel("IP-Adresse"); JLabel portLabel = new JLabel("Port"); + // Textfelder JTextField ipTextField = new JTextField(20); JTextField portTextField = new JTextField(20); + // Buttons JButton losButton = new JButton("Los!"); JButton backButton = new JButton(backButtonIcon); + // Font Font robotoFont = new Font("Roboto", Font.BOLD, 45); - public JoinGame(MainFrame frame,int g) { + /** + * Erstellt mittels Funktionsaufrufen das Panel. + * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. + * @param g int-Anzeige, ob es sich um "spiel erstellen" oder "spiel beitreten" handelt. + * @param playerType int-Anzeige, ob es sich um einen HumanPlayer,AIEasy... handelt. + * @param playerName Name des Spielers + */ + public JoinGame(MainFrame frame,int g,int playerType,String playerName) { setLayout(null); - buildPanel(frame,g); + buildPanel(frame,g,playerType,playerName); } - private void buildPanel(MainFrame frame,int g) { + /** + * Erstellt das Panel. + * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. + * @param g int-Anzeige, ob es sich um "spiel erstellen" oder "spiel beitreten" handelt. + * @param playerType int-Anzeige, ob es sich um einen HumanPlayer,AIEasy... handelt. + * @param playerName Name des Spielers + */ + private void buildPanel(MainFrame frame,int g,int playerType,String playerName) { if(g==1){ spielBeitretenLabel= new JLabel("Spiel beitreten"); }else{ @@ -41,12 +59,14 @@ public class JoinGame extends JPanel { losButton.setBounds(320, 225, 100, 50); backButton.setBounds(1380, 20, 80, 80); - ipLabel.setBounds(50, 125, 200, 30); portLabel.setBounds(50, 200, 200, 30); - ipTextField.setBounds(50, 150, 250, 50); - portTextField.setBounds(50, 225, 250, 50); + if(g==1) { //Wenn man Spiel erstellen will werden IP-Felder nicht angezeigt. + ipLabel.setBounds(50, 125, 200, 30); + ipTextField.setBounds(50, 150, 250, 50); + } + portTextField.setBounds(50, 225, 250, 50); spielBeitretenLabel.setFont(robotoFont.deriveFont(50f)); @@ -57,22 +77,45 @@ public class JoinGame extends JPanel { add(ipTextField); add(portTextField); add(backButton); + // ActionListener für Buttons + // Um in das MultiplayerGame zurückzuwechseln. + backButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + frame.showPanel("MultiplayerGame"); + } + }); - backButton.addActionListener(e -> frame.showPanel("MultiplayerGame")); - losButton.addActionListener(e -> frame.showPanel("Verbinden")); - /* + // Um das Verbinden Panel anzuzeigen und Daten an Backend weiterzureichen. losButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - frame.showPanel("Verbinden"); - //public static void startOnlineGame(Class localPlayerClass, String localPlayerName, InetSocketAddress - // address, int size) throws IOException { - if(playerType == 1) { //Beispiel (für playertape wäre z.B. 1 humanPlayer etc.) - GameController.startOnlineGame(HumanPlayer.class, playerName, adress); // - } + String ipAddress = ipTextField.getText(); + if (ipAddress.isEmpty()) { + ipAddress = "0.0.0.0"; + } + String portText = portTextField.getText(); + + int port = Integer.parseInt(portText); + InetSocketAddress address = new InetSocketAddress(ipAddress, port); + + frame.showPanel("Verbinden"); + + try { + if(playerType == 0) { + GameController.startOnlineGame(HumanPlayer.class, playerName, address,GameController.semesterToBoardSize(2)); + } else if(playerType == 1) { + GameController.startOnlineGame(SpecificAiPlayerEasy.class, playerName, address,GameController.semesterToBoardSize(2)); + } else if (playerType == 2) { + GameController.startOnlineGame(SpecificAiPlayerMedium.class, playerName, address,GameController.semesterToBoardSize(2)); + } else if (playerType == 3) { + GameController.startOnlineGame(SpecificAiPlayerHard.class, playerName, address,GameController.semesterToBoardSize(2)); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } } }); - */ } } \ No newline at end of file diff --git a/src/MainFrame.java b/src/MainFrame.java index 9afa7d2..75b27ba 100644 --- a/src/MainFrame.java +++ b/src/MainFrame.java @@ -1,6 +1,10 @@ import javax.swing.*; import java.awt.*; +/** + * Der MainFrame dient als Hub und Übergreifendes Fenster auf dem alle weiteren Panel angezeigt werden. + * Dadurch werden keine weiteren Fenster geöffnet. + */ public class MainFrame extends JFrame { private CardLayout cardLayout; @@ -16,40 +20,36 @@ public class MainFrame extends JFrame { int semesterCounter; // ---------- // - + /** + * Konstruktor von MainFrame. + * Ermöglicht es Panel anzuzeigen. + */ public MainFrame() { + + GameController.setMainFrame(this); + setTitle("Studium Versenken"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(1500, 1000); setLocationRelativeTo(null); - //JLabel backgroundLabel = new JLabel(new ImageIcon("graphics/mainmenubackground.png")); - // backgroundLabel.setBounds(0, 0, 1500, 1000); - // getContentPane().add(backgroundLabel); - - // backgroundLabel.setOpaque(true); - // CardLayout und Hauptpanel erstellen cardLayout = new CardLayout(); mainPanel = new JPanel(cardLayout); - // Verschiedene Panels erstellen und hinzufügen + // Panels erstellen MainMenuView mainMenuView = new MainMenuView(this); startLocalGame localGame = new startLocalGame(this); - //startLocalGameLoadingScreen LocalGameLoadingScreen = new startLocalGameLoadingScreen(this); startMultiplayerGame multiplayerGame = new startMultiplayerGame(this); coinToss coinToss = new coinToss(this); Verbinden verbinden = new Verbinden(this); - //JoinGame joinGame = new JoinGame(this,localMult); - //GameBoard gameBoard = new GameBoard(this, localMult); + // Panels hinzufügen mainPanel.add(mainMenuView, "MainMenu"); mainPanel.add(localGame, "LocalGame"); mainPanel.add(multiplayerGame, "MultiplayerGame"); mainPanel.add(coinToss, "coinToss"); mainPanel.add(verbinden, "Verbinden"); - //mainPanel.add(joinGame, "JoinGame"); - //mainPanel.add(gameBoard, "GameBoard"); // Hauptpanel in JFrame hinzufügen add(mainPanel); @@ -58,81 +58,60 @@ public class MainFrame extends JFrame { cardLayout.show(mainPanel, "MainMenu"); } - // Methode, um die Ansicht zu wechseln + /** + * Methode, um die Ansicht zu wechseln + * @param panelName Name des anzuzeigenden Panels + */ public void showPanel(String panelName) { cardLayout.show(mainPanel, panelName); } - // --- ShowPanel der startMultiplayerGame Klasse - public void showPanelSMG(String panelName, int num) { + /** + * Spezifische ShowPanel-Funktion der startMultiplayerGame Klasse + * @param panelName Name des anzuzeigenden Panels + * @param num Hilfsvariable um abzugleichen, ob "Spiel erstellen" oder "Spiel beitreten" ausgewählt wurde + * @param playerType Spielertyp(HumanPlayer, AIEasy etc.) + * @param playerName Name des Spielers + */ + public void showPanelSMG(String panelName, int num, int playerType,String playerName) { this.localMult = num; - //if (!isPanelPresent(panelName)) { //TODO potentiell raus - JoinGame joinGame = new JoinGame(this, localMult); - mainPanel.add(joinGame, panelName); - mainPanel.revalidate(); // Refresh - mainPanel.repaint(); - //} - + JoinGame joinGame = new JoinGame(this, localMult, playerType, playerName); + mainPanel.add(joinGame, panelName); + mainPanel.revalidate(); // Refresh + mainPanel.repaint(); cardLayout.show(mainPanel, panelName); // Show the panel } - // --- ShowPanel der startLocalGameLoadingScreen Klasse (DURCH BACKEND AUFGERUFEN) + + /** + * Spezifische ShowPanel der startLocalGameLoadingScreen Klasse (DURCH BACKEND AUFGERUFEN) + * @param panelName Name des anzuzeigenden Panels + * @param semesterCounter Ausgewähltes Semester + * @param p1 Erstes Spielerobjekt + * @param p2 Zweites Spielerobjekt + */ public void showPanelSLG(String panelName,int semesterCounter, Player p1, Player p2) { - this.semesterCounter = semesterCounter; - - //if (!isPanelPresent(panelName)) { //TODO potentiell raus - // gameBoard muss player übergeben bekommen - GameBoard gameBoard = new GameBoard(this, semesterCounter, p1, p2); - //mainPanel.add(mainMenuView, "MainMenu"); - mainPanel.add(gameBoard, panelName); - mainPanel.revalidate(); // Refresh - mainPanel.repaint(); - //} + this.semesterCounter = semesterCounter; + GameBoard gameBoard = new GameBoard(this, semesterCounter, p1, p2); + mainPanel.add(gameBoard, panelName); + mainPanel.revalidate(); + mainPanel.repaint(); cardLayout.show(mainPanel, panelName); // Show the panel } - // --- ShowPanel der startLocalGame Klasse + /** + * Spezifische ShowPanel der startLocalGame Klasse + * @param panelName Name des anzuzeigenden Panels + * @param semesterCounter Ausgewähltes Semester + */ public void showPanelSLGLS(String panelName,int semesterCounter) { this.semesterCounter = semesterCounter; - // gameBoard muss player übergeben bekommen + startLocalGameLoadingScreen LocalGameLoadingScreen = new startLocalGameLoadingScreen(this, semesterCounter); mainPanel.add(LocalGameLoadingScreen, panelName); mainPanel.revalidate(); // Refresh mainPanel.repaint(); - //} - cardLayout.show(mainPanel, panelName); // Show the panel } - - /* TODO ist dies unnötig? - private boolean isPanelPresent(String panelName) { - for (Component component : mainPanel.getComponents()) { - if (panelName.equals(mainPanel.getClientProperty("name"))) { - return true; - } - } - return false; - } */ - - // Methoden für übergabe von playern an GameBoard - /* - public void setPlayerData() { - this.semesterCounter = semesterCounter; - - //if (!isPanelPresent(panelName)) { //TODO potentiell raus - // gameBoard muss player übergeben bekommen - GameBoard gameBoard = new GameBoard(this, semesterCounter); - mainPanel.add(gameBoard, panelName); - mainPanel.revalidate(); // Refresh - mainPanel.repaint(); - }*/ - - - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - MainFrame frame = new MainFrame(); - frame.setVisible(true); - }); - } } \ No newline at end of file diff --git a/src/OnlinePlayer.java b/src/OnlinePlayer.java index 88ac476..3634c1f 100644 --- a/src/OnlinePlayer.java +++ b/src/OnlinePlayer.java @@ -4,13 +4,15 @@ public abstract class OnlinePlayer extends Player implements AsyncSocketListener protected boolean hasReceivedCoinPackage; - public OnlinePlayer(int size, AsyncSocket socket) { + public OnlinePlayer(Integer size, AsyncSocket socket) { this.socket = socket; this.wantedBoardSize = size; socket.setHandler(this); //TODO Auto-generated constructor stub } + public abstract void sendIAM(); + public abstract void receive(String message); @Override diff --git a/src/OnlinePlayer_1_1_0.java b/src/OnlinePlayer_1_1_0.java index 6c2a784..31fe50d 100644 --- a/src/OnlinePlayer_1_1_0.java +++ b/src/OnlinePlayer_1_1_0.java @@ -1,12 +1,11 @@ import java.util.List; public class OnlinePlayer_1_1_0 extends OnlinePlayer { - public OnlinePlayer_1_1_0(int size, AsyncSocket socket) { + public OnlinePlayer_1_1_0(Integer size, AsyncSocket socket) { super(size, socket); } - @Override public void receive(String message) { SocketPackage p = new SocketPackage(message); @@ -26,6 +25,8 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { this.createBoard(usedBoardSize); this.enemy.createBoard(usedBoardSize); + GameController.startGameWithInstancedPlayers((LocalPlayer)this.enemy, (Player)this, usedBoardSize); + break; // TODO: IAMU @@ -66,6 +67,12 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { } } + @Override + public synchronized void sendIAM() { + if (this.enemy == null) throw new RuntimeException("enemy has not yet been defined"); + socket.send(new SocketPackage("IAM", GameController.boardSizeToSemester(this.wantedBoardSize) + " " + this.enemy.name)); + } + @Override public synchronized void receiveShoot(Point point){ super.socket.send(new SocketPackage("SHOOT",point.toString())); diff --git a/src/Player.java b/src/Player.java index faf9abb..8b6f6f1 100644 --- a/src/Player.java +++ b/src/Player.java @@ -43,6 +43,9 @@ public abstract class Player { return this.name; } + public Board getBoard() { + return this.board; + } public abstract void receiveCoin(boolean coin); } diff --git a/src/Ship.java b/src/Ship.java index 0c3c7f6..3be924b 100644 --- a/src/Ship.java +++ b/src/Ship.java @@ -159,4 +159,15 @@ public class Ship { public boolean isSunk() { return sunk; } + + public void setHorizontal(boolean horizontal) { + this.horizontal = horizontal; + } + + public int getSize() { + return size; + } + public String getName() { + return name; + } } diff --git a/src/SoundHandler.java b/src/SoundHandler.java index f9d04a3..ade013e 100644 --- a/src/SoundHandler.java +++ b/src/SoundHandler.java @@ -1,8 +1,10 @@ import javazoom.jl.decoder.JavaLayerException; import javazoom.jl.player.Player; +import java.awt.List; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -10,6 +12,8 @@ public class SoundHandler { private static boolean soundOn = true; + private static ArrayList runningThreads = new ArrayList(); + // Wenn fehler beim erstellen von .jar mit sound hier gucken private static HashMap sounds = new HashMap(Map.of( "hit", "./Sound/water-drip.mp3" @@ -17,7 +21,7 @@ public class SoundHandler { public static void playSound(String soundName) { if (soundOn) { - new Thread(new Runnable() { + Thread thread = new Thread(new Runnable() { @Override public void run() { try { @@ -27,9 +31,23 @@ public class SoundHandler { e.printStackTrace(); } } - }).start(); - + }); + thread.start(); + runningThreads.add(thread); } + for (Thread oldThread : runningThreads) { + if (!oldThread.isAlive()) { + + try { + oldThread.join(); + runningThreads.remove(oldThread); + System.out.println("cleared thread"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + } } diff --git a/src/Verbinden.java b/src/Verbinden.java index ca4feb7..aeb086d 100644 --- a/src/Verbinden.java +++ b/src/Verbinden.java @@ -1,6 +1,9 @@ import javax.swing.*; import java.awt.*; +/** + * Das Verbinden Panel dient als "Überblende", während im Backend das Spiel erstellt/ eine Verbindung hergestellt wird. + */ public class Verbinden extends JPanel{ ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png"); @@ -9,12 +12,20 @@ public class Verbinden extends JPanel{ Font robotoFont = new Font("Roboto", Font.BOLD, 45); - public Verbinden(MainFrame frame) { + /** + * Konstruktor der startLocalGame. + * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. + */ + public Verbinden(MainFrame frame) { setLayout(null); buildPanel(frame); } - private void buildPanel(MainFrame frame) { + /** + * Baut Panel auf. + * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. + */ + private void buildPanel(MainFrame frame) { setLayout(new BorderLayout()); verbindenLabel.setFont(robotoFont.deriveFont(50f)); add(verbindenLabel, BorderLayout.CENTER); diff --git a/src/startLocalGame.java b/src/startLocalGame.java index cf08aa9..c9e5d55 100644 --- a/src/startLocalGame.java +++ b/src/startLocalGame.java @@ -2,12 +2,13 @@ import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -// TODO -// Evtl. ist Namen selber setzten noch unmöglich -// - +/** + * Das startLocalGame Panel dient dem Erstellen eines lokalen Spiels. + * Hier kann der Benutzer Spieler inklusive Namen und das Semester, in dem sich der Benutzer befindet, einstellen. + */ public class startLocalGame extends JPanel { // Player + // TODO: entfernen Player p1; Player p2; @@ -23,7 +24,7 @@ public class startLocalGame extends JPanel { ImageIcon aiPlayerNormalIcon = new ImageIcon("graphics/botPlayerNormal.png"); ImageIcon aiPlayerHardIcon = new ImageIcon("graphics/botPlayerHard.png"); - // Labels und Buttons + // Labels JLabel frameTitle = new JLabel("Lokales Spiel"); JLabel semesterLabel = new JLabel("Semester"); JLabel leftPlayerName = new JLabel("Name"); @@ -32,6 +33,7 @@ public class startLocalGame extends JPanel { JLabel rightPlayerIcon = new JLabel(aiPlayerEasyIcon); JLabel semesterCounterLabel = new JLabel(String.valueOf(semesterCounter)); + // Buttons JButton backButton = new JButton(backButtonIcon); JButton leftPlayerLeftButton = new JButton("<-"); JButton leftPlayerRightButton = new JButton("->"); @@ -42,12 +44,20 @@ public class startLocalGame extends JPanel { JButton startButton = new JButton("Start!"); JButton testButton = new JButton("Test"); + // Textfelder JTextField leftPlayerTextField = new JTextField(20); JTextField rightPlayerTextField = new JTextField(20); - // Methode zur Erstellung des Panels + /** + * Konstruktor der startLocalGame. + * Fügt Buttons, Textfelder und Label hinzu. + * Fügt ebenfalls ActionListeners hinzu, damit Buttons etc. ihre gewünschte Funktion haben + * + * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. + */ startLocalGame(MainFrame frame) { - setLayout(null); // Stelle das Layout des Panels ein + // Layout des Panels + setLayout(null); // Setze Komponentenpositionen frameTitle.setBounds(20, 20, 200, 30); @@ -107,8 +117,8 @@ public class startLocalGame extends JPanel { rightPlayerTextField.setText(rightPlayerNickname); add(rightPlayerTextField); - // ActionListener für Buttons + // Um das Semester zu erhöhen. semesterUpButton.addActionListener(e -> { if (semesterCounter < 6) { semesterCounter++; @@ -116,6 +126,7 @@ public class startLocalGame extends JPanel { } }); + // Um das Semester zu senken. semesterDownButton.addActionListener(e -> { if (semesterCounter > 1) { semesterCounter--; @@ -123,6 +134,7 @@ public class startLocalGame extends JPanel { } }); + // Um linken Player nach links zu "rotieren". leftPlayerLeftButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -131,6 +143,7 @@ public class startLocalGame extends JPanel { } }); + // Um linken Player nach rechts zu "rotieren". leftPlayerRightButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -139,6 +152,7 @@ public class startLocalGame extends JPanel { } }); + // Um rechten Player nach links zu "rotieren". rightPlayerLeftButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -147,6 +161,7 @@ public class startLocalGame extends JPanel { } }); + // Um den rechten Player nach rechts zu "rotieren". rightPlayerRightButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -155,9 +170,38 @@ public class startLocalGame extends JPanel { } }); - backButton.addActionListener(e -> frame.showPanel("MainMenu")); - testButton.addActionListener(e -> frame.showPanelSLG("GameBoard",1,p1,p2)); - //startButton.addActionListener(e -> frame.showPanelSLG("GameBoard", semesterCounter,p1, p2)); // TODO ECHTE FUNKTION EINFÜGEN + // Um Namen des linken Spielers zu speichern. + leftPlayerTextField.addActionListener(e -> { + leftPlayerNickname = leftPlayerTextField.getText(); + System.out.println("Linker Spielername geändert zu: " + leftPlayerNickname); // Debugging-Ausgabe + }); + + // Um Namen des linken Spielers zu speichern, auch wenn nicht Enter gedrückt wird. + leftPlayerTextField.addFocusListener(new java.awt.event.FocusAdapter() { + @Override + public void focusLost(java.awt.event.FocusEvent evt) { + leftPlayerNickname = leftPlayerTextField.getText(); + System.out.println("Linker Spielername geändert zu: " + leftPlayerNickname); // Debugging-Ausgabe + } + }); + + // Um zum MainMenu zu wechseln. + backButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + frame.showPanel("MainMenu"); + } + }); + + // Um zum Gameboard zu wechseln. + testButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + frame.showPanelSLG("GameBoard",1,p1,p2); + } + }); + + // Um zum startLocalGameLoadingScreen zu wechseln und Daten an Backend weiterzureichen. startButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -200,7 +244,11 @@ public class startLocalGame extends JPanel { }); } + // Hilfsfunktionen + /** + * Setzt das jeweils "nächste" Icon, wenn der leftPlayerLeftButton gedrückt wird. + */ private void toggleLeftPlayerIconLeft() { if (leftPlayerIcon.getIcon() == humanPlayerIcon) { leftPlayerIcon.setIcon(aiPlayerHardIcon); @@ -213,6 +261,9 @@ public class startLocalGame extends JPanel { } } + /** + * Setzt das jeweils "nächste" Icon, wenn der leftPlayerRightButton gedrückt wird. + */ private void toggleLeftPlayerIconRight() { if (leftPlayerIcon.getIcon() == humanPlayerIcon) { leftPlayerIcon.setIcon(aiPlayerEasyIcon); @@ -225,6 +276,9 @@ public class startLocalGame extends JPanel { } } + /** + * Setzt das jeweils "nächste" Icon, wenn der RightPlayerLeftButton gedrückt wird. + */ private void toggleRightPlayerIconLeft() { if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) { rightPlayerIcon.setIcon(aiPlayerHardIcon); @@ -235,6 +289,9 @@ public class startLocalGame extends JPanel { } } + /** + * Setzt das jeweils "nächste" Icon, wenn der RightPlayerRightButton gedrückt wird. + */ private void toggleRightPlayerIconRight() { if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) { rightPlayerIcon.setIcon(aiPlayerNormalIcon); @@ -245,11 +302,13 @@ public class startLocalGame extends JPanel { } } - // Methode zum Aktualisieren der Textfelder basierend auf den ausgewählten Icons + /** + * Aktualisiert die Textfelder basierend auf den Icons + */ private void updateTextFields() { - // Linker Spieler + // Für Linken Spieler if (leftPlayerIcon.getIcon() == humanPlayerIcon) { - leftPlayerTextField.setText("Spieler 1"); + leftPlayerTextField.setText(leftPlayerNickname); } else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){ leftPlayerTextField.setText("Einfach"); } else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) { @@ -258,7 +317,7 @@ public class startLocalGame extends JPanel { leftPlayerTextField.setText("Schwer"); } - // Rechter Spieler + // Für Rechten Spieler if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon){ rightPlayerTextField.setText("Einfach"); } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) { diff --git a/src/startLocalGameLoadingScreen.java b/src/startLocalGameLoadingScreen.java index c8f180a..a704f6b 100644 --- a/src/startLocalGameLoadingScreen.java +++ b/src/startLocalGameLoadingScreen.java @@ -1,9 +1,19 @@ import javax.swing.*; import java.awt.*; -//Kann evtl. als genereller LoadingScreen verwendet werden und nicht "nur" für localGame + +/** + * Das startLocalGameLoadingScreen Panel dient als "Überblende", während im Backend das Spiel erstellt wird. + * Hier wird lediglich Text angezeigt + */ public class startLocalGameLoadingScreen extends JPanel{ + /** + * Konstruktor der startLocalGameLoadingScreen. + * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. + * @param semesterCounter Ein Zähler, der das gewählte Semester speichert (hier unbenutzt) + */ startLocalGameLoadingScreen(MainFrame frame, int semesterCounter) { - // Layout setzen + + // Layout des Panels setLayout(new BorderLayout()); // Label mit dem Text erstellen @@ -11,8 +21,8 @@ public class startLocalGameLoadingScreen extends JPanel{ loadingLabel.setHorizontalAlignment(SwingConstants.CENTER); // Horizontal zentrieren loadingLabel.setVerticalAlignment(SwingConstants.CENTER); // Vertikal zentrieren - // Schriftgröße anpassen (optional) - loadingLabel.setFont(new Font("Arial", Font.PLAIN, 18)); + // Schriftgröße anpassen + loadingLabel.setFont(new Font("Roboto", Font.BOLD, 45)); // Label zum Panel hinzufügen add(loadingLabel, BorderLayout.CENTER); diff --git a/src/startMultiplayerGame.java b/src/startMultiplayerGame.java index e536744..c9b748a 100644 --- a/src/startMultiplayerGame.java +++ b/src/startMultiplayerGame.java @@ -1,13 +1,17 @@ import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; -// TODO -// Evtl. ist Namen selber setzten noch unmöglich -// - +/** + * Das startMultiplayerGame Panel dient dem Erstellen eines Online Spiels. + * Hier kann der Benutzer Spieler inklusive Namen und das Semester, in dem sich der Benutzer befindet, einstellen. + */ public class startMultiplayerGame extends JPanel { + // Funktionshilfen - int semesterCounter = 1; // Semester Counter Label + int semesterCounter = 1; String PlayerNickname = "Spieler 1"; + // Grafiken ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png"); ImageIcon humanPlayerIcon = new ImageIcon("graphics/humanPlayer.png"); @@ -34,11 +38,18 @@ public class startMultiplayerGame extends JPanel { // Textfelder JTextField PlayerTextField = new JTextField(20); - // Konstruktor + /** + * Konstruktor der startLocalGame. + * Fügt Buttons, Textfelder und Label hinzu. + * Fügt ebenfalls ActionListeners hinzu, damit Buttons etc. ihre gewünschte Funktion haben + * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. + */ startMultiplayerGame(MainFrame frame) { - setLayout(null); // Setze das Layout für das Panel auf null - // Setze Komponentenpositionen und füge sie dem Panel hinzu + // Layout des Panels + setLayout(null); + + // Setze Komponentenpositionen frameTitle.setBounds(20, 20, 200, 30); add(frameTitle); @@ -55,7 +66,6 @@ public class startMultiplayerGame extends JPanel { semesterCounterLabel.setHorizontalAlignment(SwingConstants.CENTER); add(semesterCounterLabel); - // Füge Buttons hinzu und setze ihre Positionen backButton.setBounds(1380, 20, 80, 80); add(backButton); @@ -77,22 +87,12 @@ public class startMultiplayerGame extends JPanel { createGameButton.setBounds(1100, 550, 200, 50); add(createGameButton); - // Füge das Textfeld hinzu PlayerTextField.setBounds(50, 650, 250, 50); PlayerTextField.setText(PlayerNickname); add(PlayerTextField); - /* TODO: Muss in Lucas klasse rein. - public static void startOnlineGame(Class localPlayerClass, String localPlayerName, InetSocketAddress - address, int size) throws IOException { - */ - - //GameController.startOnlineGame(...); - - - - // ActionListener für Buttons - // SEMESTERBUTTONS + // ActionListener für Buttons + // Um das Semester zu erhöhen. semesterUpButton.addActionListener(e -> { if (semesterCounter < 6) { semesterCounter++; @@ -100,6 +100,7 @@ public class startMultiplayerGame extends JPanel { } }); + // Um das Semester zu senken. semesterDownButton.addActionListener(e -> { if (semesterCounter > 1) { semesterCounter--; @@ -107,25 +108,80 @@ public class startMultiplayerGame extends JPanel { } }); - // PLAYERTOGGLEBUTTONS + // Um Player nach links zu "rotieren". PlayerLeftButton.addActionListener(e -> { togglePlayerIconLeft(); updateTextFields(); }); + // Um Player nach rechts zu "rotieren". PlayerRightButton.addActionListener(e -> { togglePlayerIconRight(); updateTextFields(); }); - // ActionListener für den "Back" Button, um zum vorherigen Panel zurückzukehren + // Um Namen des linken Spielers zu speichern. + PlayerTextField.addActionListener(e -> { + PlayerNickname = PlayerTextField.getText(); + System.out.println("Linker Spielername geändert zu: " + PlayerNickname); // Debugging-Ausgabe + }); - backButton.addActionListener(e -> frame.showPanel("MainMenu")); - joinGameButton.addActionListener(e -> frame.showPanelSMG("JoinGame",1)); - createGameButton.addActionListener(e -> frame.showPanelSMG("JoinGame",0)); + // Um Namen des linken Spielers zu speichern, auch wenn nicht Enter gedrückt wird. + PlayerTextField.addFocusListener(new java.awt.event.FocusAdapter() { + @Override + public void focusLost(java.awt.event.FocusEvent evt) { + PlayerNickname = PlayerTextField.getText(); + System.out.println("Linker Spielername geändert zu: " + PlayerNickname); // Debugging-Ausgabe + } + }); + + // Um zum MainMenu zu wechseln. + backButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + frame.showPanel("MainMenu"); + } + }); + + // Um zu JoinGame mit richtigen Parametern zu wechseln. + joinGameButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (PlayerIcon.getIcon() == humanPlayerIcon) { + frame.showPanelSMG("JoinGame",1,0, PlayerNickname); + } else if ( PlayerIcon.getIcon() == aiPlayerEasyIcon) { + frame.showPanelSMG("JoinGame",1,1, PlayerNickname); + } else if ( PlayerIcon.getIcon() == aiPlayerNormalIcon) { + frame.showPanelSMG("JoinGame",1,2, PlayerNickname); + } else if ( PlayerIcon.getIcon() == aiPlayerHardIcon) { + frame.showPanelSMG("JoinGame",1,3, PlayerNickname); + } + } + }); + + // Um zu JoinGame mit richtigen Parametern zu wechseln. + createGameButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + //Parameter -> panelName, Spiel erstellen oder beitreten (int), Spielertyp(int 0-3), Spielername + if (PlayerIcon.getIcon() == humanPlayerIcon) { // TODO Wird name wirklich weitergegeben? + frame.showPanelSMG("JoinGame",0,0, PlayerNickname); + } else if ( PlayerIcon.getIcon() == aiPlayerEasyIcon) { + frame.showPanelSMG("JoinGame",0,1, PlayerNickname); + } else if ( PlayerIcon.getIcon() == aiPlayerNormalIcon) { + frame.showPanelSMG("JoinGame",0,2, PlayerNickname); + } else if ( PlayerIcon.getIcon() == aiPlayerHardIcon) { + frame.showPanelSMG("JoinGame",0,3, PlayerNickname); + } + } + }); } - // TOGGLE METHODEN + // Hilfsfunktionen + + /** + * Setzt das jeweils "nächste" Icon, wenn der PlayerLeftButton gedrückt wird. + */ private void togglePlayerIconLeft() { if (PlayerIcon.getIcon() == humanPlayerIcon) { PlayerIcon.setIcon(aiPlayerHardIcon); @@ -138,6 +194,9 @@ public class startMultiplayerGame extends JPanel { } } + /** + * Setzt das jeweils "nächste" Icon, wenn der PlayerRightButton gedrückt wird. + */ private void togglePlayerIconRight() { if (PlayerIcon.getIcon() == humanPlayerIcon) { PlayerIcon.setIcon(aiPlayerEasyIcon); @@ -150,9 +209,12 @@ public class startMultiplayerGame extends JPanel { } } + /** + * Aktualisiert die Textfelder basierend auf den Icons + */ private void updateTextFields() { if (PlayerIcon.getIcon() == humanPlayerIcon) { - PlayerTextField.setText("Spieler 1"); + PlayerTextField.setText(PlayerNickname); } else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){ PlayerTextField.setText("Einfach"); } else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) { @@ -161,4 +223,4 @@ public class startMultiplayerGame extends JPanel { PlayerTextField.setText("Schwer"); } } -} +} \ No newline at end of file