Compare commits

..

No commits in common. "bfb25dfe2c2189d1033ca8c41ad9ffb1ab07a75b" and "f20896566c402957550ecfba099014b385edfbfa" have entirely different histories.

40 changed files with 472 additions and 1767 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 889 B

View File

@ -1,17 +1,8 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
public abstract class AiPlayer extends LocalPlayer {
public abstract class AiPlayer extends LocalPlayer implements Runnable {
List<Thread> shootThreads;
public AiPlayer() {
this.setName("AI Player");
this.shootThreads = new ArrayList<>();
}
public AiPlayer() {}
public Point RandomPoint() {
Random random = new Random(); // Pseudo Random für zufallszahlen
int posx = random.nextInt(super.board.getSize()); // Generiert 0 - 13
@ -19,78 +10,15 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
return new Point(posx,posy);
}
@Override
public void createBoard(int size) {
super.createBoard(size);
this.aiSetShips();
this.ready();
}
public void aiSetShips() {
public void AiSetShips() {
for(int i = 0; i < super.board.getShips().size(); i++) { // Interiert durch alle Shiffe
//TODO: set horizontal
while(!super.board.getShips().get(i).setPosition(RandomPoint(), true, super.board.getShips(), super.board.getSize())) {}
while(!super.board.getShips().get(i).setPosition(RandomPoint(), super.board.getShips(), super.board.getSize())) {}
} // Versucht das Aktuelle Shiff zu setzten und wiederholt solange bis es funktioniert
return;
}
public void aiShoot() {
this.enemy.receiveShoot(RandomPoint());
public void AiShoot() {
super.board.hit(RandomPoint());
return;
}
@Override
public synchronized void receiveHit(HitResponse hitResponse) {
super.receiveHit(hitResponse);
if (this.myTurn) {
Thread t = new Thread(this);
t.start();
this.shootThreads.add(t);
}
}
@Override
public synchronized void receiveShoot(Point point) {
super.receiveShoot(point);
if (this.myTurn) {
Thread t = new Thread(this);
t.start();
this.shootThreads.add(t);
}
}
@Override
public void beginTurn() {
Thread t = new Thread(this);
t.start();
this.shootThreads.add(t);
}
public void run() {
Iterator<Thread> i = this.shootThreads.iterator();
while(i.hasNext()) {
Thread thread = i.next();
if (!thread.isAlive()) {
try {
thread.join();
i.remove();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.aiShoot();
}
}

View File

@ -1,86 +1,27 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.io.PrintWriter;
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 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();
}
private PrintWriter out;
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 BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
this.out = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream()));
this.handler = handler;
this.shouldStop = false;
this.checkerThread = new Thread(() -> {
while (!this.shouldStop) {
try {
@ -88,38 +29,21 @@ 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) {
@ -127,36 +51,21 @@ public class AsyncSocket {
}
public synchronized void send(SocketPackage socketPackage) {
public void send(SocketPackage socketPackage) {
this.sendLine(socketPackage.toString());
}
public synchronized void send(String packageName) {
public void send(String packageName) {
this.send(packageName, "");
}
public synchronized void send(String packageName, String packageContent) {
public void send(String packageName, String packageContent) {
if (packageContent.length() > 0) {
packageContent = " " + packageContent;
}
this.sendLine(packageName + packageContent);
}
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 sendLine(String message) {
this.out.print(message + "\r\n");
}
public void close() {
@ -164,11 +73,8 @@ public class AsyncSocket {
try {
this.socket.close();
this.checkerThread.join();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -1,5 +1,4 @@
import java.util.ArrayList;
import java.util.List;
public class Board {
@ -11,8 +10,6 @@ public class Board {
public Board(int size) {
this.size = size;
this.ships = new ArrayList<>();
this.hits = new ArrayList<>();
this.createShip(size - 13);
}
@ -21,7 +18,7 @@ public class Board {
for (int i = 0; i < this.ships.size(); i++) {
HitResponseType type = this.ships.get(i).shootOnShip(point);
if ( type == HitResponseType.SUNK) {
for (int ii = 0; ii < this.ships.size(); ii++) {
for (int ii = 0; i < this.ships.size(); ii++) {
if (!this.ships.get(ii).isSunk()) {
response.setType(type);
this.addHits(response);
@ -42,19 +39,6 @@ public class Board {
return response;
}
private void propagateSunk(Point p) {
HitResponse hit = this.getHitResponseOnPoint(p);
if (hit == null || hit.getType() != HitResponseType.HIT) return;
hit.setType(HitResponseType.SUNK);
propagateSunk(new Point(p.getX() + 1, p.getY()));
propagateSunk(new Point(p.getX() - 1, p.getY()));
propagateSunk(new Point(p.getX(), p.getY() + 1));
propagateSunk(new Point(p.getX(), p.getY() - 1));
}
private void createShip(int semester){
List<ShipData> shipData = Ship.semeterList.get(semester -1);
for (int i = 0; i < shipData.size(); i++) {
@ -67,21 +51,14 @@ public class Board {
}
public synchronized boolean addHits(HitResponse hitResponse) {
if (this.getHitResponseOnPoint(hitResponse.getPoint()) == null){
if (this.getHitResponsOnPoint(hitResponse.getPoint()) == null){
this.hits.add(hitResponse);
//Propagate sunk for display purposes
if (hitResponse.getType() == HitResponseType.SUNK) {
hitResponse.setType(HitResponseType.HIT);
propagateSunk(hitResponse.getPoint());
}
return true;
}
return false;
}
public synchronized HitResponse getHitResponseOnPoint(Point point) {
public synchronized HitResponse getHitResponsOnPoint(Point point) {
for (int i = 0; i < this.hits.size(); i++){
if (this.hits.get(i).getPoint().equals(point)){
return this.hits.get(i);

View File

@ -1,253 +0,0 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
/**
* Dient dem Aufbau der Matrix (Spielfeld) und füllt diese mit Funktion
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public class BoardDisplay extends JPanel {
private JButton[][] fields;
private int gridSize;
private Ship currentShip;
private Player player;
private boolean horizontal = false;
private List<ShipButton> shipButtonList;
private boolean enemyBoard;
private Point mousePosition;
/**
* Fügt Buttons zu Liste hinzu und aktualisiert Feld durch Aufruf von paintFields
* @param button
* @author Joshua Kuklok
*/
public void addShipButton(ShipButton button) {
shipButtonList.add(button);
paintFields();
}
/**
* Gibt currentShip zurück
* @return currentShip
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public Ship getCurrentShip() {
return currentShip;
}
/**
* Konstruktor der startLocalGame.
* @param gridSize Die Größe des Spielfelds
* @param player Der Spieler
* @author Lucas Bronson
*/
public BoardDisplay(int gridSize, Player player, boolean enemyBoard) {
super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Spalte
this.fields = new JButton[gridSize][gridSize];
this.shipButtonList = new ArrayList<>();
this.player = player;
this.gridSize = gridSize;
this.enemyBoard = enemyBoard;
// Erstellung vom Spielfeld
for (int i = 0; i <= gridSize; i++) {
for (int j = 0; j <= gridSize; j++) {
final int x = j - 1; // Temporäre Variable
final int y = i - 1; // Temporäre Variable
if (i == 0 && j == 0) {
add(new JLabel(" "));
} else if (i == 0) {
JLabel colLabel = new JLabel(String.valueOf(j));
colLabel.setHorizontalAlignment(SwingConstants.CENTER);
colLabel.setFont(new Font("Roboto", Font.BOLD, 14));
add(colLabel);
} else if (j == 0) {
JLabel rowLabel = new JLabel(String.valueOf((char) ('A' + i - 1)));
rowLabel.setHorizontalAlignment(SwingConstants.CENTER);
rowLabel.setFont(new Font("Arial", Font.BOLD, 14));
add(rowLabel);
} else {
// Spielfeld (interaktive Zellen)
JButton field = new JButton("");
field.setBackground(Color.BLUE);
field.setOpaque(true);
field.setBorderPainted(true);
fields[x][y] = field;
add(field);
// Um Mausinteraktionen zu ermöglichen (Rechts/- Linksklick, Hover)
field.addMouseListener(new MouseAdapter() {
// Um beim "Hovern" Position zu setzten und weiterzugeben.
@Override
public void mouseEntered(MouseEvent e) {
mousePosition = new Point(x, y);
paintFields();
}
// Um nach "wegbewegen" der Maus wieder zu entfärben
@Override
public void mouseExited(MouseEvent e) {
paintFields();
}
// Um Schiffe zu rotieren/platzieren
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
togglePlacementDirection();
} else if (SwingUtilities.isLeftMouseButton(e)) {
Point o = new Point(x, y);
handleFieldClick(o);
SoundHandler.playSound("plop");
}
}
});
}
}
}
}
/**
* Aktuelles Schiff auswählen
* @param ship Schiff zum Auswählen
* @author Lucas Bronson, Joshua Kuklok
*/
public void selectCurrentShip(Ship ship) {
this.currentShip = ship;
paintFields();
}
/**
* Zurücksetzen von aktuellem Schiff und allen Schiffen des Spielers.
* Danach blau färben des Spielfeldes
* @author Lucas Bronson, Joshua Kuklok
*/
public void resetAllShips() {
this.currentShip = null;
for (Ship ship : player.getBoard().getShips()) {
ship.resetPosition();
}
paintFields();
}
/**
* Wechselt die Platzierungsrichtung zwischen horizontal und vertikal.
* @author Lucas Bronson, Joshua Kuklok
*/
private void togglePlacementDirection() {
horizontal = !horizontal;
String direction = horizontal ? "horizontal" : "vertikal";
System.out.println("Platzierungsrichtung geändert zu: " + direction);
paintFields();
}
/**
* Handhabt das Platzieren eines Schiffs auf dem Spielfeld.
* @param o Die Koordinaten des Klicks.
* @author Lucas Bronson, Luca Conte
*/
private void handleFieldClick(Point o) {
System.out.println("CLICK " + o);
if (!this.enemyBoard && !this.player.isGameRunning() && !this.player.isReady()) {
this.currentShip.setPosition(o, horizontal, player.getBoard().getShips(),this.gridSize);
}
if (this.enemyBoard && this.player.isGameRunning() && this.player.enemy.myTurn) {
this.player.enemy.shoot(o);
}
paintFields();
}
/**
* Färbt das Spielfeld blau, überprüft, ob das aktuelle Schiff null ist.
* Färbt eine Preview in das Spielfeld ein, ob Schiff setzen möglich ist
* Schiffe die gesetzt wurden, werden grau gefärbt
* Aufrufen von refreshButtonState um zu zeigen, ob Button drückbar ist
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public void paintFields() {
List<Point> test=new ArrayList<>();
if(currentShip != null) {
test = currentShip.getVirtualOccupiedPoints(mousePosition, horizontal);
}
for(int i = 0; i < gridSize; i++) {
for(int j = 0; j < gridSize; j++) {
if(fields[i][j] == null) {
continue;
}
if (this.enemyBoard) {
// enemy board only accessible if game is running AND it's "enemy's" so local player's turn
if (!this.player.isGameRunning() || !this.player.enemy.myTurn) {
fields[i][j].setEnabled(false);
} else {
fields[i][j].setEnabled(true);
}
} else {
if (this.player.isGameRunning() || this.player.isReady()) {
fields[i][j].setEnabled(false);
} else {
fields[i][j].setEnabled(true);
}
}
if (this.enemyBoard) {
fields[i][j].setBackground(Color.WHITE);
} else {
fields[i][j].setBackground(Color.BLUE);
}
if (!this.player.isReady()) {
for(Point p : test) {
if(i==p.getX() && j==p.getY()) {
if (currentShip.checkValidPlacement(mousePosition,horizontal,player.getBoard().getShips(),gridSize)) {
fields[i][j].setBackground(Color.GREEN);
} else {
fields[i][j].setBackground(Color.RED);
}
}
}
}
for(Ship ship: player.getBoard().getShips()) {
if(ship.isShipOnPos(new Point(i,j))) {
fields[i][j].setBackground(Color.LIGHT_GRAY);
}
}
HitResponse hit = this.player.getBoard().getHitResponseOnPoint(new Point(i, j));
if (hit != null) {
switch (hit.getType()) {
case HIT:
fields[i][j].setBackground(Color.ORANGE);
//SoundHandler.playSound("hit");
break;
case SUNK:
//SoundHandler.playSound("destroyed");
case VICTORY:
fields[i][j].setBackground(Color.RED);
break;
case MISS:
if (this.enemyBoard) {
//SoundHandler.playSound("miss");
fields[i][j].setBackground(Color.BLUE);
} else {
fields[i][j].setBackground(Color.CYAN);
}
break;
}
}
}
}
for( ShipButton shipButton: shipButtonList) {
shipButton.refreshButtonState();
}
}
/**
* Ruft paintFields auf, um Felder zu aktualisieren
* @author Luca Conte
*/
public void refresh() {
paintFields();
}
}

View File

@ -2,168 +2,89 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public class GameBoard extends JPanel {
private BoardDisplay ownBoardPanel;
private BoardDisplay opponentBoardPanel;
private Player p1;
private Player p2;
// Funktionshilfen
//int semesterCounter = 1; //TODO: ersetzen durch param von vorpanel
// Grafiken
ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png");
ImageIcon gameBoardEmtpy = new ImageIcon("graphics/gameboardempty.png");
ImageIcon gameBoardX = new ImageIcon("graphics/gameboardx.png");
// kontextText Text-Strings
String kT1 = "Bitte Schiffe setzten";
String kT2 = "Warte auf Gegner";
String kT3 = "Du fängst an";
String kT4 = "Dein Gegner fängt an";
String kT5 = "Du bist am Zug";
String kT6 = "Dein Gegner ist am Zug";
String kT7 = "Du hast das Spiel gewonnen";
String kT8 = "Du hast das Spiel verloren";
String kT9 = "Bitte erst alle Schiffe setzten";
// Labels
JLabel frameTitle = new JLabel("GameBoard");
JLabel kontextText = new JLabel(kT1);
JLabel kontextText = new JLabel("Beispielhafter Kontext-Text");
//kontextText.setFont(new Font("Roboto", Font.BOLD, 24)); //TODO setFont fixen
// Buttons
JButton giveUpButton = new JButton("Aufgeben");
JButton backButton = new JButton(backButtonIcon);
// Eigene ModulButtons
JButton leftPlayerModul1 = new JButton("Modul 1"); //TODO: Dynamische Namen durch abgleich mit Semester
JButton leftPlayerModul2 = new JButton("Modul 2");
JButton leftPlayerModul3 = new JButton("Modul 3");
JButton leftPlayerModul4 = new JButton("Modul 4");
JButton leftPlayerModul5 = new JButton("Modul 5");
JButton leftPlayerModul6 = new JButton("Modul 6");
JButton leftPlayerModul7 = new JButton("Reset");
// Gegnerische ModulButtons
JButton rightPlayerModul1 = new JButton("Modul 1");
JButton rightPlayerModul2 = new JButton("Modul 2");
JButton rightPlayerModul3 = new JButton("Modul 3");
JButton rightPlayerModul4 = new JButton("Modul 4");
JButton rightPlayerModul5 = new JButton("Modul 5");
JButton rightPlayerModul6 = new JButton("Modul 6");
JButton rightPlayerModul7 = new JButton("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
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
GameBoard(MainFrame frame, int semesterCounter,Player p1, Player p2) {
this.p1 = p1;
this.p2 = p2;
buildPanel(frame, semesterCounter);
List<Ship> shipsP1 =p1.getBoard().getShips();
List<Ship> shipsP2 =p2.getBoard().getShips();
giveUpButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Hier könnte Ihr Backend Code stehen
frame.showPanel("MainMenu");
}
});
}
// Timer für pulsierenden SchwarzGrau-Effekt
Timer timer = new Timer(10, new ActionListener() {
// Start-Grauwert (0 = Schwarz, 255 = Weiß)
private int value = 50;
private boolean increasing = false;
@Override
public void actionPerformed(ActionEvent e) {
kontextText.setForeground(new Color(value, value, value));
if (increasing) {
value++;
if (value >= 90) {
increasing = false;
}
} else {
value--;
if (value <= 0) {
increasing = true;
}
}
}
});
/**
* Baut das grundlegende Spielboard
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @param semesterCounter Ausgewähltes Semester
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public void buildPanel(MainFrame frame, int semesterCounter) {
// Hauptlayout - BorderLayout für die Anordnung der Komponenten
setLayout(new BorderLayout());
// Spielfelder erstellen (eigenes und gegnerisches)
// Spielfelder werden in BoardDisplay erstellt
int gridSize = GameController.semesterToBoardSize(semesterCounter); // Größe des Spielfelds
this.ownBoardPanel = new BoardDisplay(gridSize,p1, false);
this.opponentBoardPanel = new BoardDisplay(gridSize, p2, true);
// Panel für das Kontext-Text-Feld
JPanel headerPanel = new JPanel();
headerPanel.setLayout(new BorderLayout());
headerPanel.add(kontextText, BorderLayout.WEST);
kontextText.setFont(new Font("Roboto", Font.BOLD, 30)); //TODO setFont fixen
headerPanel.add(giveUpButton, BorderLayout.EAST);
JPanel leftButtonsPanel = new JPanel();
leftButtonsPanel.setLayout(new GridLayout(7, 1)); // 6 Buttons untereinander
JPanel rightButtonsPanel = new JPanel();
rightButtonsPanel.setLayout(new GridLayout(7, 1));
//Buttons in eine Gruppe packen damit diese beim drücken eines anderen Buttons wieder entwählt werden
ButtonGroup leftButtonGroup= new ButtonGroup();
ButtonGroup rightButtonGroup= new ButtonGroup();
headerPanel.add(backButton, BorderLayout.EAST);
// Panel für die Buttons des linken Spielers (ganz links)
for(Ship ship : p1.getBoard().getShips()) {
ShipButton shipButton= new ShipButton(ship,ownBoardPanel);
leftButtonsPanel.add(shipButton);
leftButtonGroup.add(shipButton);
ownBoardPanel.addShipButton(shipButton);
JPanel leftButtonsPanel = new JPanel();
leftButtonsPanel.setLayout(new GridLayout(7, 1)); // 6 Buttons untereinander
leftButtonsPanel.add(leftPlayerModul1);
leftButtonsPanel.add(leftPlayerModul2);
leftButtonsPanel.add(leftPlayerModul3);
leftButtonsPanel.add(leftPlayerModul4);
leftButtonsPanel.add(leftPlayerModul5);
leftButtonsPanel.add(leftPlayerModul6);
leftButtonsPanel.add(leftPlayerModul7);
// Panel für die Buttons des rechten Spielers (ganz rechts)
JPanel rightButtonsPanel = new JPanel();
rightButtonsPanel.setLayout(new GridLayout(7, 1)); // 6 Buttons untereinander
rightButtonsPanel.add(rightPlayerModul1);
rightButtonsPanel.add(rightPlayerModul2);
rightButtonsPanel.add(rightPlayerModul3);
rightButtonsPanel.add(rightPlayerModul4);
rightButtonsPanel.add(rightPlayerModul5);
rightButtonsPanel.add(rightPlayerModul6);
rightButtonsPanel.add(rightPlayerModul7);
// Spielfelder erstellen (eigenes und gegnerisches)
int gridSize = 13 + semesterCounter; // Größe des Spielfelds
JPanel ownBoardPanel = new JPanel(new GridLayout(gridSize, gridSize));
JPanel opponentBoardPanel = new JPanel(new GridLayout(gridSize, gridSize));
// Buttons für das eigene Spielfeld hinzufügen
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridSize; j++) {
ownBoardPanel.add(new JButton(gameBoardEmtpy));
}
}
for(Ship ship : p2.getBoard().getShips()) {
ShipButton shipButton= new ShipButton(ship,opponentBoardPanel);
rightButtonsPanel.add(shipButton);
rightButtonGroup.add(shipButton);
opponentBoardPanel.addShipButton(shipButton);
shipButton.setEnabled(false);
}
JToggleButton readyButton = new JToggleButton("Bereit");
readyButton.setBackground(Color.GREEN);
rightButtonsPanel.add(readyButton);
JToggleButton resetButton = new JToggleButton("Reset");
resetButton.setBackground(Color.RED);
leftButtonsPanel.add(resetButton);
resetButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ownBoardPanel.resetAllShips();
}
});
// TODO buttons erst disablen wenn alle Schiffe platziert sind
// Um Bereit-Meldung and Backend zu geben, kontextText zu setzten und ready/reset Button zu deaktivieren
readyButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
kontextText.setText(kT2);
p1.ready();
if(true) {
readyButton.setEnabled(false);
resetButton.setEnabled(false);
// Buttons für das gegnerische Spielfeld hinzufügen
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridSize; j++) {
opponentBoardPanel.add(new JButton(gameBoardEmtpy));
}
}
});
// Panel für beide Spielfelder (nebeneinander in der Mitte)
JPanel centerPanel = new JPanel();
@ -171,55 +92,23 @@ public class GameBoard extends JPanel {
centerPanel.add(ownBoardPanel);
centerPanel.add(opponentBoardPanel);
// Spieler-Namen über den Spielfeldern hinzufügen
JPanel playerNamesPanel = new JPanel();
playerNamesPanel.setLayout(new GridLayout(1, 2)); // Zwei Labels nebeneinander
JLabel player1NameLabel = new JLabel(p1.getName(), SwingConstants.CENTER);
JLabel player2NameLabel = new JLabel(p2.getName(), SwingConstants.CENTER);
System.out.println("Name in Gameboard: " + player1NameLabel.getText());
// Schrift und Formatierung der Labels
player1NameLabel.setFont(new Font("Roboto", Font.BOLD, 18));
player2NameLabel.setFont(new Font("Roboto", Font.BOLD, 18));
// Spieler-Labels zum Panel hinzufügen
playerNamesPanel.add(player1NameLabel);
playerNamesPanel.add(player2NameLabel);
// Spieler-Namen-Panel oberhalb der Spielfelder hinzufügen
JPanel namesAndBoardsPanel = new JPanel(new BorderLayout());
namesAndBoardsPanel.add(playerNamesPanel, BorderLayout.NORTH);
namesAndBoardsPanel.add(centerPanel, BorderLayout.CENTER);
// Panels dem Hauptlayout hinzufügen
add(leftButtonsPanel, BorderLayout.WEST);
add(rightButtonsPanel, BorderLayout.EAST);
add(headerPanel, BorderLayout.NORTH);
add(namesAndBoardsPanel, BorderLayout.CENTER);
timer.start();
add(centerPanel, BorderLayout.CENTER);
}
/**
* Aktualisiert Zustand(kontextText) je nach Zug
* @author Luca Conte
*/
public void refresh() {
if (this.p1.myTurn) {
this.kontextText.setText(kT5);
} else {
this.kontextText.setText(kT6);
GameBoard(MainFrame frame,int semesterCounter) {
buildPanel(frame, semesterCounter);
/*
rightPlayerRightButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
toggleRightPlayerIcon();
updateTextFields();
}
this.ownBoardPanel.refresh();
this.opponentBoardPanel.refresh();
}); */
backButton.addActionListener(e -> frame.showPanel("MainMenu"));
}
/**
* Getter für Player1
* @return Player 1
* @author Peer Ole Wachtel
*/
public Player getP1() {
return p1;
}
}

View File

@ -1,5 +1,8 @@
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;
@ -16,12 +19,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<String, Class<? extends OnlinePlayer>> supportedVersions = new HashMap<>(Map.of(
"1.1.0", OnlinePlayer_1_1_0.class
@ -30,15 +33,34 @@ public class GameController {
public static void startOnlineGame(Class<? extends LocalPlayer> localPlayerClass, String localPlayerName, InetSocketAddress address, int size) throws IOException {
AsyncSocket clientSocket;
boolean localPlayerIsServer = address.getHostName() == null || address.getHostName().isEmpty() || address.getHostName().equals("0.0.0.0");
boolean localPlayerIsServer = address.getHostName() == null;
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
clientSocket = new AsyncSocket(address, null);
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.send("VERSION", "Gruppe03 " + String.join(" ", supportedVersions.keySet()));
@ -62,24 +84,17 @@ public class GameController {
OnlinePlayer onlinePlayer;
try {
localPlayer = localPlayerClass.getDeclaredConstructor().newInstance();
onlinePlayer = onlinePlayerClass.getDeclaredConstructor(Integer.class, AsyncSocket.class).newInstance((Integer)size, clientSocket);
onlinePlayer = onlinePlayerClass.getDeclaredConstructor().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");
}
@ -160,23 +175,15 @@ public class GameController {
throw new RuntimeException("Unable to instantiate players");
}
localPlayer.isServer = true;
aiPlayer.isServer = false;
localPlayer.setEnemy(aiPlayer);
aiPlayer.setEnemy(localPlayer);
localPlayer.createBoard(size);
aiPlayer.createBoard(size);
localPlayer.setName(localPlayerName);
startGameWithInstancedPlayers(localPlayer, aiPlayer, size);
startGameWithInstancedPlayers(localPlayer, aiPlayer);
}
public static void startGameWithInstancedPlayers(LocalPlayer p1, Player p2, int boardSize) {
mainFrame.showPanelSLG("GameBoard", boardSizeToSemester(boardSize), p1, p2);
private static void startGameWithInstancedPlayers(LocalPlayer p1, Player p2) {
p1.setEnemy(p2);
p2.setEnemy(p1);
// TODO: frontend configuration
}

View File

@ -1,26 +1,21 @@
/**
* Hauptklasse über die der MainFrame gestartet wird
* @author Lucas Bronson, Ole Wachtel, Joshua Kuklok
*/
public class HalloSchiffeVersenken {
/**
* Erstellt und setzt den Mainframe
* @param args Argumente an Main durch Konsole etc.
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
MainFrame mf = new MainFrame();
mf.setVisible(true);
System.out.println("HelloSchiffeVersenekn");
System.out.println("sound");
SoundHandler.playSound("hit");
Thread.sleep(10000);
SoundHandler.setSoundOn(false);
System.out.println("sound off");
SoundHandler.playSound("hit");
}
}
/*
*TODO
* Alle Textfonts anpassen
* SOUND interrupt?
* BACKEND aufruf bei aufgeben
* check bevor ready ob alle schiffe platziert?
* testcode rausnehmen
* FidgetButton als surprise (button während spiels, der zufällig farbe wechseln kann und sounds abspielt)
*/

View File

@ -1,58 +1,27 @@
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetSocketAddress;
/**
* Das JoinGame Panel dient zum setzten des Ports/IP-Adresse.
* Anschließend kann das Verbinden Panel gezeigt werden.
* @author Lucas Bronson
*/
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);
/**
* 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
* @author Lucas Bronson, Joshua Kuklok
*/
public JoinGame(MainFrame frame,int g,int playerType,String playerName) {
public JoinGame(MainFrame frame,int g) {
setLayout(null);
buildPanel(frame,g,playerType,playerName);
buildPanel(frame,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
* @author Lucas Bronson, Joshua Kuklok
*/
private void buildPanel(MainFrame frame,int g,int playerType,String playerName) {
private void buildPanel(MainFrame frame,int g) {
if(g==1){
spielBeitretenLabel= new JLabel("Spiel beitreten");
}else{
@ -63,15 +32,13 @@ 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);
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));
add(spielBeitretenLabel);
@ -82,45 +49,7 @@ public class JoinGame extends JPanel {
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");
}
});
// Um das Verbinden Panel anzuzeigen und Daten an Backend weiterzureichen.
losButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
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);
}
}
});
backButton.addActionListener(e -> frame.showPanel("MultiplayerGame"));
losButton.addActionListener(e -> frame.showPanel("Verbinden"));
}
}

View File

@ -10,7 +10,7 @@ public class LocalPlayer extends Player {
@Override
public synchronized void receiveShoot(Point point) {
HitResponse hitResponse = board.getHitResponseOnPoint(point);
HitResponse hitResponse = board.getHitResponsOnPoint(point);
if (!(hitResponse == null)){
enemy.receiveHit(hitResponse);
@ -22,9 +22,8 @@ public class LocalPlayer extends Player {
switch (hitResponse.getType()) {
case HIT, SUNK -> this.myTurn = false;
case MISS -> this.myTurn = true;
case VICTORY -> GameController.getMainFrame().showPanelLoose("", this); //TODO Was halt bei victory passiert ist hier wurder verloheren
case VICTORY -> System.out.println("Game Over"); //TODO Was halt bei victory passiert ist hier wurder verloheren
}
GameController.getMainFrame().refreshGameBoard();
}
@Override
@ -33,31 +32,27 @@ public class LocalPlayer extends Player {
switch (hitResponse.getType()) {
case HIT, SUNK -> this.myTurn = true;
case MISS -> this.myTurn = false;
case VICTORY -> GameController.getMainFrame().showPanelWin("", this); // TODO was halt beim victory passier ist hier wurde gewonnen
case VICTORY -> System.out.println("Win"); // TODO was halt beim victory passier ist hier wurde gewonnen
}
GameController.getMainFrame().refreshGameBoard();
}
@Override
public synchronized void receiveCoin(boolean coin) {
if (!this.hasReceivedCoin) {
this.hasReceivedCoin = true;
this.determineCoinToss();
if (!this.haseReceivedCoin) {
boolean result = coin ^ this.myCoin; // XOR
this.myTurn = result == this.isServer;
this.haseReceivedCoin = true;
}
}
public void sendCoin() {
enemy.receiveCoin(this.myCoin);
}
@Override
public void shoot(Point point){
this.myTurn = false;
enemy.receiveShoot(point);
}
@Override
public synchronized void ready() {
for (Ship ship : this.board.getShips()) {
if (!ship.isPlaced()) return;
}
super.ready();
}
}

View File

@ -1,34 +0,0 @@
import java.awt.*;
import javax.swing.*;
/**
* Klasse für Erstellung von looseScreen Objekten
* Dient zur Anzeige das ein Spiel verloren wurde
*/
public class LooseScreen extends JPanel {
JLabel looseLabel = new JLabel("Du hast Verloren");
JButton okButton = new JButton("Zurück zum Hauptmenü");
Font robotoFont = new Font("Roboto", Font.BOLD, 45);
/**
* Konstruktor der LooseScreen Klasse
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public LooseScreen(MainFrame frame) {
setLayout(new BorderLayout());
buildPanel(frame);
}
/**
* Panel bauen/Objekte hinzufügen
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public void buildPanel(MainFrame frame) {
add(looseLabel);
okButton.setBounds(650,525,200,50);
looseLabel.setBounds(500,450,500,50);
looseLabel.setFont(robotoFont);
}
}

View File

@ -1,11 +1,6 @@
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.
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public class MainFrame extends JFrame {
private CardLayout cardLayout;
@ -16,45 +11,43 @@ public class MainFrame extends JFrame {
// Von startMultiplayerGame an JoinGame
int localMult;
// Von startLocalGame an startLocalGameLoadingScreen
// Von startLocalGameLoadingScreen an GameBoard
// Von startLocalGame an GameBoard
int semesterCounter;
// ---------- //
private GameBoard gameBoard;
/**
* Konstruktor von MainFrame.
* Ermöglicht es Panel anzuzeigen.
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
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);
// Panels erstellen
// Verschiedene Panels erstellen und hinzufügen
MainMenuView mainMenuView = new MainMenuView(this);
startLocalGame localGame = new startLocalGame(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(winLooseScreen, "WinLooseScreen");
//mainPanel.add(joinGame, "JoinGame");
//mainPanel.add(gameBoard, "GameBoard");
// Hauptpanel in JFrame hinzufügen
add(mainPanel);
@ -63,109 +56,50 @@ public class MainFrame extends JFrame {
cardLayout.show(mainPanel, "MainMenu");
}
/**
* Methode, um die Ansicht zu wechseln
* @param panelName Name des anzuzeigenden Panels
* @author Joshua Kuklok
*/
// Methode, um die Ansicht zu wechseln
public void showPanel(String panelName) {
cardLayout.show(mainPanel, panelName);
}
/**
* 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
* @author Lucas Bronson, Joshua Kuklok
*/
public void showPanelSMG(String panelName, int num, int playerType,String playerName) {
// --- ShowPanel der startMultiplayerGame Klasse
public void showPanelSMG(String panelName, int num) {
this.localMult = num;
JoinGame joinGame = new JoinGame(this, localMult, playerType, playerName);
//if (!isPanelPresent(panelName)) { //TODO potentiell raus
JoinGame joinGame = new JoinGame(this, localMult);
mainPanel.add(joinGame, panelName);
mainPanel.revalidate();
mainPanel.revalidate(); // Refresh
mainPanel.repaint();
cardLayout.show(mainPanel, panelName);
}
//}
/**
* 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
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public void showPanelSLG(String panelName,int semesterCounter, Player p1, Player p2) {
cardLayout.show(mainPanel, panelName); // Show the panel
}
// --- ShowPanel der startLocalGame Klasse
public void showPanelSLG(String panelName,int semesterCounter) {
this.semesterCounter = semesterCounter;
this.gameBoard = new GameBoard(this, semesterCounter, p1, p2);
//if (!isPanelPresent(panelName)) { //TODO potentiell raus
GameBoard gameBoard = new GameBoard(this, semesterCounter);
mainPanel.add(gameBoard, panelName);
mainPanel.revalidate();
mainPanel.revalidate(); // Refresh
mainPanel.repaint();
cardLayout.show(mainPanel, panelName); // Panel anzeigen
}
//}
/**
* Spezifische ShowPanel der startLocalGame Klasse
* @param panelName Name des anzuzeigenden Panels
* @param semesterCounter Ausgewähltes Semester
* @author Joshua Kuklok
*/
public void showPanelSLGLS(String panelName,int semesterCounter) {
this.semesterCounter = semesterCounter;
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;
} */
startLocalGameLoadingScreen LocalGameLoadingScreen = new startLocalGameLoadingScreen(this, semesterCounter);
mainPanel.add(LocalGameLoadingScreen, panelName);
mainPanel.revalidate();
mainPanel.repaint();
cardLayout.show(mainPanel, panelName); // Panel anzeigen
}
/**
* Spezifische ShowPanel für WinScreen Klasse
* @param panelName Name des anzuzeigenden Panels
* @param player Player von dem die funktion aufgerufen worden ist
* @author Lucas Bronson, Peer Ole Wachtel
*/
public void showPanelWin(String panelName, Player player){
if(player != gameBoard.getP1()){
return;
}
WinScreen winScreen = new WinScreen(this);
mainPanel.add(winScreen, panelName);
mainPanel.revalidate();
mainPanel.repaint();
cardLayout.show(mainPanel, panelName);
}
/**
* Spezifische ShowPanel für LooseScreen Klasse
* @param panelName Name des anzuzeigenden Panels
* @param player Player von dem die funktion aufgerufen worden ist
* @author Lucas Bronson, Peer Ole Wachtel
*/
public void showPanelLoose(String panelName, Player player){
if(player != gameBoard.getP1()){
return;
}
LooseScreen looseScreen = new LooseScreen(this);
mainPanel.add(looseScreen,panelName);
mainPanel.revalidate();
mainPanel.repaint();
cardLayout.show(mainPanel, panelName);
}
/**
* Aktualisiert das Spielfeld (kontextText)
* @author Luca Conte
*/
public void refreshGameBoard() {
if(this.gameBoard == null) {
return;
}
this.gameBoard.refresh();
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MainFrame frame = new MainFrame();
frame.setVisible(true);
});
}
}

View File

@ -0,0 +1,35 @@
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MainMenuController implements ActionListener {
private MainMenuView view;
private MainMenuModel model;
public MainMenuController(MainMenuModel model, MainMenuView view) {
this.view = view;
this.model = model;
//this.view.getLocalButton().addActionListener(this);
//this.view.getMultiButton().addActionListener(this);
// this.view.getSoundButton().addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
//if (e.getSource() == view.getMultiButton()) {
// model.setGameMode("Multiplayer");
// MultiMenuModel multiModel = new MultiMenuModel();
// MultiMenuView multiView = new MultiMenuView();
// MultiMenuController multiMenuController = new MultiMenuController(multiModel, multiView);
// view.addPanel(multiView.getMultiPanel(), "MultiMenu");
// view.showPanel("MultiMenu");
// }else if (e.getSource() == view.getSoundButton()) {
// view.toggleMute();
// }else if(e.getSource() == view.getLocalButton()) {
model.setGameMode("LocalGame");
//startLocalGame localGame = new startLocalGame();
// view.addPanel(localGame.getLocalPanel(), "LocalMenu");
// view.showPanel("LocalMenu");
}
}
//}

11
src/MainMenuModel.java Normal file
View File

@ -0,0 +1,11 @@
public class MainMenuModel {
private String gameMode;
public void setGameMode(String mode) {
this.gameMode = mode;
}
public String getGameMode() {
return gameMode;
}
}

View File

@ -1,13 +1,9 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.*;
/**
* Klasse zum Erstellen von MainMenu Objekten
* Dient als Hauptmenü für die Anwendung
* @author Lucas Bronson
*/
public class MainMenuView extends JPanel {
private JLabel titelLabel = new JLabel("Studium versenken");
@ -19,21 +15,11 @@ public class MainMenuView extends JPanel {
private ImageIcon soundIcon = new ImageIcon("graphics/sound button.png");
private ImageIcon muteIcon = new ImageIcon("graphics/sound button muted.png");
/**
* Konstruktor der MainMenuView Klasse
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public MainMenuView(MainFrame frame) {
setLayout(null);
buildPanel(frame);
}
/**
* Methode zum Füllen des Panels, Objekte werden dem frame hinzugefügt
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
private void buildPanel(MainFrame frame) {
lokalButton.setBounds(200, 200, 500, 500);
multiButton.setBounds(800, 200, 500, 500);
@ -50,7 +36,7 @@ public class MainMenuView extends JPanel {
add(multiButton);
add(soundButton);
// ActionListener um vom Hauptmenü zum LocalGame Menü zu wechseln
// Event Listener für Buttons
lokalButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -59,7 +45,6 @@ public class MainMenuView extends JPanel {
}
});
// ActionListener um vom Hauptmenü zum MultiPlayerGame Menü zu wechseln
multiButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -68,7 +53,6 @@ public class MainMenuView extends JPanel {
}
});
//Aufruf von toggleMute, falls der soundButton geklickt wird
soundButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -78,18 +62,11 @@ public class MainMenuView extends JPanel {
});
}
/**
* Setzt Sound auf Stumm/Laut und ändert Grafik, sodass
* der aktuelle Stand der Grafik entspricht
* @author Lucas Bronson, Joshua Kuklok
*/
private void toggleMute() {
if (soundButton.getIcon() == soundIcon) {
soundButton.setIcon(muteIcon);
SoundHandler.setSoundOn(false);
} else {
soundButton.setIcon(soundIcon);
SoundHandler.setSoundOn(true);
}
}
}

View File

@ -0,0 +1,22 @@
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MultiMenuController implements ActionListener {
private MultiMenuView view;
private MultiMenuModel model;
public MultiMenuController(MultiMenuModel model, MultiMenuView view) {
this.view = view;
this.model = model;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == view.getPlayerLeftButton()){
view.togglePlayerIcon();
}else if(e.getSource() == view.getPlayerRightButton()){
view.togglePlayerIcon();
}
}
}

11
src/MultiMenuModel.java Normal file
View File

@ -0,0 +1,11 @@
public class MultiMenuModel {
private String gameMode;
public void setGameMode(String mode) {
this.gameMode = mode;
}
public String getGameMode() {
return gameMode;
}
}

83
src/MultiMenuView.java Normal file
View File

@ -0,0 +1,83 @@
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.*;
public class MultiMenuView {
int semesterCounter = 1;
private JPanel multiPanel = new JPanel(null);
private ImageIcon humanPlayerIcon = new ImageIcon("graphics/humanPlayer.png");
private ImageIcon aiPlayerIcon = new ImageIcon("graphics/aiPlayer.png");
JButton PlayerLeftButton = new JButton("<-");
JButton PlayerRightButton = new JButton("->");
JButton semesterUpButton = new JButton("^");
JButton semesterDownButton = new JButton("v");
JLabel semesterLabel = new JLabel("Semester");
private JLabel titelLabel = new JLabel("Multiplayer");
private JLabel PlayerIcon = new JLabel(humanPlayerIcon);
private JLabel PlayerName = new JLabel("Name");
private JTextField PlayerTextField = new JTextField(20);
JLabel semesterCounterLabel = new JLabel(String.valueOf(semesterCounter));
private Font robotoFont = new Font("Roboto", Font.BOLD, 45);
public MultiMenuView() {
buildPanel();
}
public void buildPanel(){
titelLabel.setBounds(20,20,700,100);
PlayerIcon.setBounds(75, 400, 200, 128);
PlayerName.setBounds(50, 625, 200, 30);
PlayerTextField.setBounds(50, 650, 250, 50);
semesterCounterLabel.setBounds(725, 475, 50, 50); // zwischen den Up/Down-Buttons
PlayerLeftButton.setBounds(50, 450, 50, 50);
PlayerRightButton.setBounds(250, 450, 50, 50);
semesterLabel.setBounds(500, 400, 200, 30);
semesterUpButton.setBounds(700, 400, 50, 50);
semesterDownButton.setBounds(700, 550, 50, 50);
multiPanel.setLayout(null);
titelLabel.setFont(robotoFont.deriveFont(50f));
semesterLabel.setFont(robotoFont.deriveFont(20f));
multiPanel.add(PlayerName);
multiPanel.add(titelLabel);
multiPanel.add(PlayerIcon);
multiPanel.add(PlayerTextField);
multiPanel.add(semesterCounterLabel);
multiPanel.add(semesterUpButton);
multiPanel.add(semesterDownButton);
multiPanel.add(PlayerLeftButton);
multiPanel.add(PlayerRightButton);
multiPanel.add(semesterLabel);
}
public JPanel getMultiPanel() {
return multiPanel;
}
//public void showMultiPanel(String panelName) {
// CardLayout cl = (CardLayout)mainPanel.getLayout();
// cl.show(multiPanel, panelName);
//}
public void togglePlayerIcon() {
if (PlayerIcon.getIcon() == humanPlayerIcon) {
PlayerIcon.setIcon(aiPlayerIcon);
} else {
PlayerIcon.setIcon(humanPlayerIcon);
}
}
public JButton getPlayerLeftButton() {
return PlayerLeftButton;
}
public JButton getPlayerRightButton() {
return PlayerRightButton;
}
}

View File

@ -4,16 +4,13 @@ public abstract class OnlinePlayer extends Player implements AsyncSocketListener
protected boolean hasReceivedCoinPackage;
public OnlinePlayer(Integer size, AsyncSocket socket) {
public OnlinePlayer(int size, AsyncSocket socket) {
this.socket = socket;
this.wantedBoardSize = size;
this.myCoin = null;
socket.setHandler(this);
//TODO Auto-generated constructor stub
}
public abstract void sendIAM();
public abstract void receive(String message);
@Override

View File

@ -1,11 +1,12 @@
import java.util.List;
public class OnlinePlayer_1_1_0 extends OnlinePlayer {
public OnlinePlayer_1_1_0(Integer size, AsyncSocket socket) {
public OnlinePlayer_1_1_0(int size, AsyncSocket socket) {
super(size, socket);
}
@Override
public void receive(String message) {
SocketPackage p = new SocketPackage(message);
@ -25,8 +26,6 @@ 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
@ -34,7 +33,7 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
case "COIN":
if(!this.hasReceivedCoinPackage && (p.getData().equals("1") || p.getData().equals("0"))){
this.myCoin = p.getData().equals("1");
this.ready();
enemy.receiveCoin(this.myCoin);
this.hasReceivedCoinPackage = true;
}
break;
@ -67,12 +66,6 @@ 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()));
@ -85,10 +78,9 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
@Override
public synchronized void receiveCoin(boolean coin) {
if (!this.hasReceivedCoin) {
if (!this.haseReceivedCoin) {
super.socket.send(new SocketPackage("COIN", String.valueOf(coin ? 1 : 0)));
this.hasReceivedCoin = true;
this.determineCoinToss();
this.haseReceivedCoin = true;
}
}

View File

@ -1,3 +1,5 @@
import java.util.Random;
public abstract class Player {
protected boolean myTurn;
protected boolean isServer;
@ -5,19 +7,15 @@ public abstract class Player {
protected Player enemy;
protected String name;
protected Board board;
protected Boolean myCoin;
protected boolean gameRunning;
protected boolean myCoin;
protected boolean sentCoin;
protected boolean sendCoin;
protected boolean hasReceivedCoin;
protected boolean haseReceivedCoin;
public Player() {
this.setName("Player");
this.hasReceivedCoin = false;
this.sentCoin = false;
this.myTurn = false;
this.gameRunning = false;
this.haseReceivedCoin = false;
this.sendCoin = false;
}
public void createBoard(int size) {
@ -30,8 +28,8 @@ public abstract class Player {
public abstract void shoot(Point point);
public void beginTurn() {
System.out.println("issa my turn-a");
public void beginTrun() {
}
public void setEnemy(Player enemy) {
@ -45,36 +43,6 @@ public abstract class Player {
return this.name;
}
public Board getBoard() {
return this.board;
}
public void ready() {
this.enemy.receiveCoin(this.myCoin);
this.sentCoin = true;
if (hasReceivedCoin) {
this.determineCoinToss();
}
};
protected void determineCoinToss() {
if (!this.sentCoin || this.myCoin == null || !this.hasReceivedCoin || this.enemy.myCoin == null) return;
boolean result = this.enemy.myCoin ^ this.myCoin; // XOR
this.myTurn = result == this.isServer;
if (this.myTurn) {
this.beginTurn();
}
this.gameRunning = true;
GameController.getMainFrame().refreshGameBoard();
}
public abstract void receiveCoin(boolean coin);
public boolean isGameRunning() {
return this.gameRunning;
}
public boolean isReady() {
return this.sentCoin;
}
}

View File

@ -9,7 +9,7 @@ public class Point {
public Point (String str) {
if (Point.isValidSyntax(str)) {
this.setX(str.charAt(0));
this.setY(Integer.parseInt(str.substring(1)) - 1);
this.setY(Integer.parseInt(str.substring(1)));
} else {
throw new IllegalArgumentException("String ist keine gültige Koordinate");
}
@ -17,7 +17,7 @@ public class Point {
@Override
public String toString() {
return (char) ('A' + this.x) + String.valueOf(this.y + 1);
return (char) ('A' + this.x) + String.valueOf(this.y);
}
public int getX() {
@ -42,18 +42,4 @@ public class Point {
public static boolean isValidSyntax(String str) {
return str.matches("^[A-Z]\\d+$");
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || this.getClass() != o.getClass()) return false;
Point p = (Point)o;
return p.getX() == this.getX() && p.getY() == this.getY();
}
public boolean neighbours(Point other) {
if (other == null) return false;
return (int)Math.abs(this.getX() - other.getX()) <= 1 && (int)Math.abs(this.getY() - other.getY()) <= 1;
}
}

View File

@ -61,20 +61,7 @@ public class Ship {
this.sunk = false;
}
public void resetPosition() {
this.position = null;
}
public boolean setPosition(Point pos, boolean horizontal, List<Ship> shipsList, int boardSize) {
if (!this.checkValidPlacement(pos, horizontal, shipsList, boardSize)) return false;
// kein ueberlappen also setze das Schiff
this.position = pos;
this.horizontal = horizontal;
return true;
}
public boolean checkValidPlacement(Point pos, boolean horizontal, List<Ship> shipsList, int boardSize) {
public boolean setPosition(Point pos, List<Ship> shipsList, int boardSize) {
// ueberpruefe boundaries
if (pos.getX() < 0 || pos.getY() < 0 || pos.getX() >= boardSize || pos.getY() >= boardSize) {
return false;
@ -84,7 +71,7 @@ public class Ship {
int endX = pos.getX();
int endY = pos.getY();
if (horizontal) { // rechts links
if (this.horizontal) { // rechts links
endX = pos.getX() + this.size - 1;
if (endX >= boardSize) {
return false;
@ -97,7 +84,12 @@ public class Ship {
}
// Liste an Punkten die das Schiff einnehmen wuerde
List<Point> shipPoints = this.getVirtualOccupiedPoints(pos, horizontal);
List<Point> shipPoints = new ArrayList<>();
for (int i = 0; i < this.size; i++) {
int x = this.horizontal ? pos.getX() + i : pos.getX(); //falls horizontal dann pos.x + i ansonsten pos.x
int y = this.horizontal ? pos.getY() : pos.getY() + i;
shipPoints.add(new Point(x, y));
}
// ueberlappen mit anderen Schiffen pruefen
for (Ship otherShip : shipsList) {
@ -113,28 +105,16 @@ public class Ship {
List<Point> otherShipPoints = otherShip.getOccupiedPoints();
// ueberlappen checken
for (Point p : shipPoints) {
for (Point otherPoint : otherShipPoints) {
if (otherPoint.neighbours(p)) return false;
if (otherShipPoints.contains(p)) {
// ueberlappen entdeckt
return false;
}
}
}
return true;
}
/**
* Returns the Points on the ship if it were to be placed at positino `pos` in orientation defined by `horizontal`
*/
public List<Point> getVirtualOccupiedPoints(Point pos, boolean horizontal) {
List<Point> points = new ArrayList<>();
if (pos == null) {
return points;
}
for (int i = 0; i < this.size; i++) {
int x = horizontal ? pos.getX() + i : pos.getX();
int y = horizontal ? pos.getY() : pos.getY() + i;
points.add(new Point(x, y));
}
return points;
// kein ueberlappen also setze das Schiff
this.position = pos;
return true;
}
public List<Point> getOccupiedPoints() {
@ -155,9 +135,6 @@ public class Ship {
}
public boolean isShipOnPos(Point pos){
if(this.position == null){
return false;
}
if ((this.horizontal && pos.getY() == this.position.getY() && pos.getX() >= this.position.getX() && pos.getX() < this.position.getX() + size) ||
(!(this.horizontal) && pos.getX() == this.position.getX() && pos.getY() >= this.position.getY() && pos.getY() < this.position.getY() + size)) {
return true;
@ -182,20 +159,4 @@ 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;
}
//potentiell falsch neu
public boolean isPlaced(){
return this.position != null;
}
}

View File

@ -1,44 +0,0 @@
import javax.swing.*;
import java.awt.*;
/**
* Das ShipButton Panel dient dem Erstellen eines lokalen Spiels.
* Hier kann der Benutzer Spieler inklusive Namen und das Semester, in dem sich der Benutzer befindet, einstellen.
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public class ShipButton extends JButton {
private Ship ship;
private BoardDisplay boardDisplay;
/**
* TODO fertig beschreiben
* @param ship
* @param boardDisplay
* @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/
public ShipButton(Ship ship, BoardDisplay boardDisplay) {
super(ship.getName());
this.ship = ship;
this.boardDisplay = boardDisplay;
this.addActionListener((e) -> {
boardDisplay.selectCurrentShip(this.ship);
});
}
/**
* Setzt Farbe der Modulbuttons.
* Verschiedene Farben für:
* Modul ausgewählt, platziert nicht platziert.
* @author Joshua Kuklok
*/
public void refreshButtonState() {
if (ship.isPlaced()) {
setBackground(Color.LIGHT_GRAY);
} else {
setBackground(Color.WHITE);
}
if (boardDisplay.getCurrentShip() == ship) {
setBackground(Color.CYAN);
}
}
}

View File

@ -1,41 +1,23 @@
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.Iterator;
import java.util.Map;
/**
* Der SoundHandler dient zum Anlegen und Abspielen von Sounds
* @author Lucas Bronson, Luca Conte, Ole Wachtel, Joshua Kuklok
*/
public class SoundHandler {
private static boolean soundOn = true;
private static ArrayList<Thread> runningThreads = new ArrayList<Thread>();
// Wenn fehler beim erstellen von .jar mit sound hier gucken
private static HashMap<String, String> sounds = new HashMap<String, String>(Map.of(
"miss", "./Sound/water-drip.mp3",
"hit", "./Sound/hit.mp3",
"destroyed", "./Sound/hit.mp3",
"plop", "./Sound/plop.mp3",
"loose", "./Sound/loosescreenWAH.mp3"
"hit", "./Sound/water-drip.mp3"
));
/**
* Erstellt neuen Thread, um ausgewählten Sound abzuspielen
* @param soundName Name der Audiodatei, welche abgespielt werden soll
* @author Ole Wachtel, Luca Conte
*/
public static void playSound(String soundName) {
if (soundOn) {
Thread thread = new Thread(new Runnable() {
new Thread(new Runnable() {
@Override
public void run() {
try {
@ -45,42 +27,16 @@ public class SoundHandler {
e.printStackTrace();
}
}
});
thread.start();
runningThreads.add(thread);
}
Iterator<Thread> i = runningThreads.iterator();
while (i.hasNext()) {
Thread oldThread = i.next();
if (!oldThread.isAlive()) {
try {
oldThread.join();
i.remove();
System.out.println("cleared thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
/**
* TODO funktion beschreiben (potentiell nicht benötigte Funktion?)
* @param soundName
* @param path
* @author Ole Wachtel
*/
static void add(String soundName, String path){
sounds.put(soundName, path);
}
/**
* TODO funktion beschreiben (potentiell nicht benötigte Funktion?)
* @param sound
* @author Ole Wachtel
*/
static void setSoundOn(boolean sound){
soundOn= sound;
}

View File

@ -1,9 +1,3 @@
public class SpecificAiPlayerEasy extends AiPlayer{
public SpecificAiPlayerEasy() {
super();
this.setName("AI Player Easy");
}
}

View File

@ -1,125 +1,3 @@
import java.util.ArrayList;
import java.util.Random;
public class SpecificAiPlayerHard extends AiPlayer{
private int gridSize;
private boolean[][] shotsFired;
private final ArrayList<Point> hitQueue;
private final Random random;
private int nextChessRow;
private int nextChessCol;
public SpecificAiPlayerHard() {
super();
this.setName("AI Player Hard");
/*this.gridSize = super.board.getSize();
this.shotsFired = new boolean[gridSize][gridSize];*/
this.gridSize = 0;
this.hitQueue = new ArrayList<>();
this.random = new Random();
this.nextChessRow = 0;
this.nextChessCol = 0;
}
// Checks if a position has already been shot at
public boolean alreadyShot(Point p) {
return shotsFired[p.getX()][p.getY()];
}
// Generates the next move for the AI
public Point getNextMove() {
if(gridSize == 0) {
this.gridSize = super.board.getSize();
this.shotsFired = new boolean[gridSize][gridSize];
}
// If there are hits to process, prioritize those
while (!hitQueue.isEmpty()) {
Point target = hitQueue.remove(0);
if (!alreadyShot(target)) {
return target;
}
}
// Otherwise, use chess pattern targeting
int row = nextChessRow;
int col = nextChessCol;
while (alreadyShot(new Point(row, col))) {
advanceChessPattern();
row = nextChessRow;
col = nextChessCol;
}
shotsFired[row][col] = true;
advanceChessPattern();
return new Point(row, col);
}
@Override
public synchronized void receiveHit(HitResponse hitResponse) {
super.receiveHit(hitResponse);
// If it's a hit or sunk, add adjacent cells to the hitsQueue
if (hitResponse.getHitResponse() == HitResponseType.HIT) {
addAdjacentPoints(hitResponse.getPoint());
}
}
private void addAdjacentPoints(Point point) {
int x = point.getX();
int y = point.getY();
// Possible adjacent positions (up, down, left, right)
Point[] adjacentPoints = {
new Point(x, y - 1),
new Point(x, y + 1),
new Point(x - 1, y),
new Point(x + 1, y)
};
for (Point p : adjacentPoints) {
if (isValidPoint(p) && !alreadyShot(p) && !hitQueue.contains(p)) {
hitQueue.add(p);
}
}
}
private boolean isValidPoint(Point point) {
return point.getX() >= 0 && point.getX() < gridSize &&
point.getY() >= 0 && point.getY() < gridSize;
}
@Override
public void aiShoot() {
this.enemy.receiveShoot(getNextMove());
}
// Advances the chess pattern to the next cell
private void advanceChessPattern() {
nextChessCol += 2;
if (nextChessCol >= gridSize) {
nextChessRow += 1;
nextChessCol = (nextChessRow % 2 == 0) ? 0 : 1; // Alternate starting points for chess pattern
}
if (nextChessRow >= gridSize) {
nextChessRow = 0;
nextChessCol = 0; // Reset if pattern wraps around
}
}
// Adds adjacent cells to the hit queue
/* public void processHit(int row, int col) {
if (row > 0 && !alreadyShot(row - 1, col)) {
hitQueue.add(new int[]{row - 1, col});
}
if (row < gridSize - 1 && !alreadyShot(row + 1, col)) {
hitQueue.add(new int[]{row + 1, col});
}
if (col > 0 && !alreadyShot(row, col - 1)) {
hitQueue.add(new int[]{row, col - 1});
}
if (col < gridSize - 1 && !alreadyShot(row, col + 1)) {
hitQueue.add(new int[]{row, col + 1});
}
}*/
}

View File

@ -5,24 +5,16 @@ public class SpecificAiPlayerMedium extends AiPlayer{
private List<Point> hitsQueue = new ArrayList<>();
public SpecificAiPlayerMedium() {
super();
this.setName("AI Player Medium");
}
@Override
public void aiShoot() {
public void AiShoot() {
Point nextShot = ComputeNextShot();
// Shoot at the enemy and receive the hit response
enemy.receiveShoot(nextShot);
}
@Override
public synchronized void receiveHit(HitResponse hitResponse) {
super.receiveHit(hitResponse);
HitResponse hitResponse = enemy.board.getHitResponsOnPoint(nextShot);
// If it's a hit or sunk, add adjacent cells to the hitsQueue
if (hitResponse.getHitResponse() == HitResponseType.HIT) {
addAdjacentPoints(hitResponse.getPoint());
addAdjacentPoints(nextShot);
}
}
@ -65,9 +57,8 @@ public class SpecificAiPlayerMedium extends AiPlayer{
}
private boolean alreadyShot(Point p) {
return this.enemy.board.getHitResponseOnPoint(p) != null;
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'alreadyShot'");
}
private boolean isValidPoint(Point point) {

View File

@ -1,10 +1,6 @@
import javax.swing.*;
import java.awt.*;
/**
* Das Verbinden Panel dient als "Überblende", während im Backend das Spiel erstellt/ eine Verbindung hergestellt wird.
* @author Lucas Bronson
*/
public class Verbinden extends JPanel{
ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png");
@ -13,21 +9,11 @@ public class Verbinden extends JPanel{
Font robotoFont = new Font("Roboto", Font.BOLD, 45);
/**
* Konstruktor der Verbinden Klasse.
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public Verbinden(MainFrame frame) {
setLayout(null);
buildPanel(frame);
}
/**
* Baut Panel auf.
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
private void buildPanel(MainFrame frame) {
setLayout(new BorderLayout());
verbindenLabel.setFont(robotoFont.deriveFont(50f));

View File

@ -1,64 +0,0 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/**
* Klasse für Erstellung von winScreen Objekten
* Dient zur Anzeige des Sieges nachdem ein Spiel
* @author Lucas Bronson
*/
public class WinScreen extends JPanel {
JLabel winLabel = new JLabel("Du hast Gewonnen!");
Font robotoFont = new Font("Roboto", Font.BOLD, 45);
JButton okButton = new JButton("Zurück zum Hauptmenü");
/**
* Konstruktor der WinScreen Klasse
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public WinScreen(MainFrame frame) {
setLayout(null);
buildPanel(frame);
}
/**
* Panel bauen/Objekte hinzufuegen
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public void buildPanel(MainFrame frame) {
Timer timer = new Timer(5, new ActionListener() {
private float hue = 0; // Farbton-Wert für HSB-Farbmodell
@Override
public void actionPerformed(ActionEvent e) {
// Farbe basierend auf dem Farbton-Wert berechnen
Color pulsierendeFarbe = Color.getHSBColor(hue, 0.8f, 0.8f); // Sättigung und Helligkeit fix
winLabel.setForeground(pulsierendeFarbe);
// Farbton leicht verändern (Zyklus zwischen 0 und 1)
hue += 0.01f;
if (hue > 1) {
hue = 0;
}
}
});
okButton.setBounds(650,525,200,50);
winLabel.setBounds(500,450,500,50);
timer.start(); // Timer starten
winLabel.setFont(robotoFont);
winLabel.setHorizontalAlignment(SwingConstants.CENTER);
//Zurückkehren zum Hauptmenü, wenn okButton gedrückt wird
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.showPanel("MainMenu");
}
});
add(winLabel);
add(okButton);
}
}

View File

@ -1,6 +1,6 @@
import javax.swing.*;
import java.awt.*;
// TODO Klasse löschen da nicht gebraucht
public class coinToss extends JPanel {
private int reihenfolge = 1; // 1 = Spieler 1 fängt an, 0 = Spieler 2 fängt an
private Timer timer;

View File

@ -1,41 +1,27 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
/**
* 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.
* @author Lucas Bronson, Joshua Kuklok
*/
public class startLocalGame extends JPanel {
// Player
// TODO: entfernen (generell auch test button)
Player p1;
Player p2;
// Funktionshilfen
int semesterCounter = 1; // Semester Counter Label
String leftPlayerNickname = "Spieler 1";
String rightPlayerNickname = "Einfach";
String rightPlayerNickname = "Spieler 2";
// Grafiken
ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png");
ImageIcon humanPlayerIcon = new ImageIcon("graphics/humanPlayer.png");
ImageIcon aiPlayerEasyIcon = new ImageIcon("graphics/botPlayerEasy.png");
ImageIcon aiPlayerNormalIcon = new ImageIcon("graphics/botPlayerNormal.png");
ImageIcon aiPlayerHardIcon = new ImageIcon("graphics/botPlayerHard.png");
ImageIcon aiPlayerIcon = new ImageIcon("graphics/aiPlayer.png");
// Labels
// Labels und Buttons
JLabel frameTitle = new JLabel("Lokales Spiel");
JLabel semesterLabel = new JLabel("Semester");
JLabel leftPlayerName = new JLabel("Name");
JLabel rightPlayerName = new JLabel("KI-Level");
JLabel leftPlayerIcon = new JLabel(humanPlayerIcon);
JLabel rightPlayerIcon = new JLabel(aiPlayerEasyIcon);
JLabel rightPlayerIcon = new JLabel(aiPlayerIcon);
JLabel semesterCounterLabel = new JLabel(String.valueOf(semesterCounter));
// Buttons
JButton backButton = new JButton(backButtonIcon);
JButton leftPlayerLeftButton = new JButton("<-");
JButton leftPlayerRightButton = new JButton("->");
@ -44,23 +30,13 @@ public class startLocalGame extends JPanel {
JButton rightPlayerLeftButton = new JButton("<-");
JButton rightPlayerRightButton = new JButton("->");
JButton startButton = new JButton("Start!");
JButton testButton = new JButton("Test");
// Textfelder
JTextField leftPlayerTextField = new JTextField(20);
JTextField rightPlayerTextField = new JTextField(20);
/**
* 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.
* @author Lucas Bronson, Joshua Kuklok
*/
// Methode zur Erstellung des Panels
startLocalGame(MainFrame frame) {
// Layout des Panels
setLayout(null);
setLayout(null); // Stelle das Layout des Panels ein
// Setze Komponentenpositionen
frameTitle.setBounds(20, 20, 200, 30);
@ -85,9 +61,6 @@ public class startLocalGame extends JPanel {
semesterCounterLabel.setHorizontalAlignment(SwingConstants.CENTER);
add(semesterCounterLabel);
testButton.setBounds(500,800,50,50);
add(testButton);
backButton.setBounds(1380, 20, 80, 80);
add(backButton);
@ -120,8 +93,7 @@ public class startLocalGame extends JPanel {
rightPlayerTextField.setText(rightPlayerNickname);
add(rightPlayerTextField);
// ActionListener für Buttons.
// Um das Semester zu erhöhen.
// ActionListener für Buttons
semesterUpButton.addActionListener(e -> {
if (semesterCounter < 6) {
semesterCounter++;
@ -129,7 +101,6 @@ public class startLocalGame extends JPanel {
}
});
// Um das Semester zu senken.
semesterDownButton.addActionListener(e -> {
if (semesterCounter > 1) {
semesterCounter--;
@ -137,218 +108,73 @@ public class startLocalGame extends JPanel {
}
});
// Um linken Player nach links zu "rotieren".
leftPlayerLeftButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
toggleLeftPlayerIconLeft();
toggleLeftPlayerIcon();
updateTextFields();
}
});
// Um linken Player nach rechts zu "rotieren".
leftPlayerRightButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
toggleLeftPlayerIconRight();
toggleLeftPlayerIcon();
updateTextFields();
}
});
// Um rechten Player nach links zu "rotieren".
rightPlayerLeftButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
toggleRightPlayerIconLeft();
toggleRightPlayerIcon();
updateTextFields();
}
});
// Um den rechten Player nach rechts zu "rotieren".
rightPlayerRightButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
toggleRightPlayerIconRight();
toggleRightPlayerIcon();
updateTextFields();
}
});
// Um Namen des linken Spielers zu speichern.
leftPlayerTextField.addActionListener(e -> {
leftPlayerNickname = leftPlayerTextField.getText();
System.out.println("Linker Spielername geändert zu: " + leftPlayerNickname); // Debugging-Ausgabe
});
backButton.addActionListener(e -> frame.showPanel("MainMenu"));
// 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
startButton.addActionListener(e -> frame.showPanelSLG("GameBoard", semesterCounter)); // TODO ECHTE FUNKTION EINFÜGEN
}
});
// 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.showPanelWin("WinPanel");
}
});
// Um zum startLocalGameLoadingScreen zu wechseln und Daten an Backend weiterzureichen.
startButton.addActionListener(new ActionListener() {
@SuppressWarnings("unchecked")
@Override
public void actionPerformed(ActionEvent e) {
HashMap<ImageIcon, Class<? extends LocalPlayer>> playerClassMap = new HashMap<>();
playerClassMap.put(humanPlayerIcon, HumanPlayer.class);
playerClassMap.put(aiPlayerEasyIcon, SpecificAiPlayerEasy.class);
playerClassMap.put(aiPlayerNormalIcon, SpecificAiPlayerMedium.class);
playerClassMap.put(aiPlayerHardIcon, SpecificAiPlayerHard.class);
frame.showPanelSLGLS("startLocalGameLoadingScreen", semesterCounter); //TODO
Class<? extends LocalPlayer> leftPlayerClass = playerClassMap.get(leftPlayerIcon.getIcon());
Class<? extends AiPlayer> rightPlayerClass = (Class<? extends AiPlayer>) playerClassMap.get(rightPlayerIcon.getIcon());
GameController.startLocalGame(
leftPlayerClass, leftPlayerNickname,
rightPlayerClass,
GameController.semesterToBoardSize(semesterCounter)
);
// if (leftPlayerIcon.getIcon() == humanPlayerIcon) {// TODO Wird name wirklich weitergegeben?
// if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// GameController.startLocalGame(HumanPlayer.class, leftPlayerNickname, SpecificAiPlayerEasy.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// GameController.startLocalGame(HumanPlayer.class, leftPlayerNickname, SpecificAiPlayerMedium.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// GameController.startLocalGame(HumanPlayer.class, leftPlayerNickname, SpecificAiPlayerHard.class, GameController.semesterToBoardSize(semesterCounter));
// }
// } else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// GameController.startLocalGame(SpecificAiPlayerEasy.class, leftPlayerNickname, SpecificAiPlayerEasy.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// GameController.startLocalGame(SpecificAiPlayerEasy.class, leftPlayerNickname, SpecificAiPlayerMedium.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// GameController.startLocalGame(SpecificAiPlayerEasy.class, leftPlayerNickname, SpecificAiPlayerHard.class, GameController.semesterToBoardSize(semesterCounter));
// }
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// GameController.startLocalGame(SpecificAiPlayerMedium.class, leftPlayerNickname, SpecificAiPlayerEasy.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// GameController.startLocalGame(SpecificAiPlayerMedium.class, leftPlayerNickname, SpecificAiPlayerMedium.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// GameController.startLocalGame(SpecificAiPlayerMedium.class, leftPlayerNickname, SpecificAiPlayerHard.class, GameController.semesterToBoardSize(semesterCounter));
// }
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// GameController.startLocalGame(SpecificAiPlayerHard.class, leftPlayerNickname, SpecificAiPlayerEasy.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// GameController.startLocalGame(SpecificAiPlayerHard.class, leftPlayerNickname, SpecificAiPlayerMedium.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// GameController.startLocalGame(SpecificAiPlayerHard.class, leftPlayerNickname, SpecificAiPlayerHard.class, GameController.semesterToBoardSize(semesterCounter));
// }
// }
}
});
}
// Hilfsfunktionen
/**
* Setzt das jeweils "nächste" Icon, wenn der leftPlayerLeftButton gedrückt wird.
* @author Joshua Kuklok
*/
private void toggleLeftPlayerIconLeft() {
private void toggleLeftPlayerIcon() {
if (leftPlayerIcon.getIcon() == humanPlayerIcon) {
leftPlayerIcon.setIcon(aiPlayerHardIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){
leftPlayerIcon.setIcon(humanPlayerIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) {
leftPlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) {
leftPlayerIcon.setIcon(aiPlayerNormalIcon);
}
}
/**
* Setzt das jeweils "nächste" Icon, wenn der leftPlayerRightButton gedrückt wird.
* @author Joshua Kuklok
*/
private void toggleLeftPlayerIconRight() {
if (leftPlayerIcon.getIcon() == humanPlayerIcon) {
leftPlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){
leftPlayerIcon.setIcon(aiPlayerNormalIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) {
leftPlayerIcon.setIcon(aiPlayerHardIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) {
leftPlayerIcon.setIcon(aiPlayerIcon);
} else {
leftPlayerIcon.setIcon(humanPlayerIcon);
}
}
/**
* Setzt das jeweils "nächste" Icon, wenn der RightPlayerLeftButton gedrückt wird.
* @author Joshua Kuklok
*/
private void toggleRightPlayerIconLeft() {
if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
rightPlayerIcon.setIcon(aiPlayerHardIcon);
} else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon){
rightPlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
rightPlayerIcon.setIcon(aiPlayerNormalIcon);
private void toggleRightPlayerIcon() {
if (rightPlayerIcon.getIcon() == humanPlayerIcon) {
rightPlayerIcon.setIcon(aiPlayerIcon);
} else {
rightPlayerIcon.setIcon(humanPlayerIcon);
}
}
/**
* Setzt das jeweils "nächste" Icon, wenn der RightPlayerRightButton gedrückt wird.
* @author Joshua Kuklok
*/
private void toggleRightPlayerIconRight() {
if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
rightPlayerIcon.setIcon(aiPlayerNormalIcon);
} else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon){
rightPlayerIcon.setIcon(aiPlayerHardIcon);
} else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
rightPlayerIcon.setIcon(aiPlayerEasyIcon);
}
}
/**
* Aktualisiert die Textfelder basierend auf den Icons
* @author Joshua Kuklok
*/
// Methode zum Aktualisieren der Textfelder basierend auf den ausgewählten Icons
private void updateTextFields() {
// Für Linken Spieler
// Linker Spieler
if (leftPlayerIcon.getIcon() == humanPlayerIcon) {
leftPlayerTextField.setText(leftPlayerNickname);
} else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){
leftPlayerTextField.setText("Einfach");
} else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) {
leftPlayerTextField.setText("Mittel");
} else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) {
leftPlayerTextField.setText("Schwer");
leftPlayerTextField.setText("Spieler 1");
} else {
leftPlayerTextField.setText("Leicht");
}
// Für Rechten Spieler
if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon){
rightPlayerTextField.setText("Einfach");
} else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
rightPlayerTextField.setText("Mittel");
} else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
rightPlayerTextField.setText("Schwer");
// Rechter Spieler
if (rightPlayerIcon.getIcon() == humanPlayerIcon) {
rightPlayerTextField.setText("Spieler 2");
} else {
rightPlayerTextField.setText("Leicht");
}
}
}

View File

@ -1,32 +0,0 @@
import javax.swing.*;
import java.awt.*;
/**
* Das startLocalGameLoadingScreen Panel dient als "Überblende", während im Backend das Spiel erstellt wird.
* Hier wird lediglich Text angezeigt
* @author Joshua Kuklok
*/
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)
* @author Joshua Kuklok
*/
startLocalGameLoadingScreen(MainFrame frame, int semesterCounter) {
// Layout des Panels
setLayout(new BorderLayout());
// Label mit dem Text erstellen
JLabel loadingLabel = new JLabel("Spiel wird gestartet, bitte warten...");
loadingLabel.setHorizontalAlignment(SwingConstants.CENTER); // Horizontal zentrieren
loadingLabel.setVerticalAlignment(SwingConstants.CENTER); // Vertikal zentrieren
// Schriftgröße anpassen
loadingLabel.setFont(new Font("Roboto", Font.BOLD, 45));
// Label zum Panel hinzufügen
add(loadingLabel, BorderLayout.CENTER);
}
}

View File

@ -1,24 +1,13 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 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.
* @author Joshua Kuklok
*/
public class startMultiplayerGame extends JPanel {
// Funktionshilfen
int semesterCounter = 1;
int semesterCounter = 1; // Semester Counter Label
String PlayerNickname = "Spieler 1";
// Grafiken
ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png");
ImageIcon humanPlayerIcon = new ImageIcon("graphics/humanPlayer.png");
ImageIcon aiPlayerEasyIcon = new ImageIcon("graphics/botPlayerEasy.png");
ImageIcon aiPlayerNormalIcon = new ImageIcon("graphics/botPlayerNormal.png");
ImageIcon aiPlayerHardIcon = new ImageIcon("graphics/botPlayerHard.png");
ImageIcon aiPlayerIcon = new ImageIcon("graphics/aiPlayer.png");
// Labels
JLabel frameTitle = new JLabel("Multiplayer Spiel");
@ -39,19 +28,11 @@ public class startMultiplayerGame extends JPanel {
// Textfelder
JTextField PlayerTextField = new JTextField(20);
/**
* 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.
* @author Joshua Kuklok
*/
// Konstruktor
startMultiplayerGame(MainFrame frame) {
setLayout(null); // Setze das Layout für das Panel auf null
// Layout des Panels
setLayout(null);
// Setze Komponentenpositionen
// Setze Komponentenpositionen und füge sie dem Panel hinzu
frameTitle.setBounds(20, 20, 200, 30);
add(frameTitle);
@ -68,6 +49,7 @@ 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);
@ -89,12 +71,13 @@ 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);
// ActionListener für Buttons
// Um das Semester zu erhöhen.
// SEMESTERBUTTONS
semesterUpButton.addActionListener(e -> {
if (semesterCounter < 6) {
semesterCounter++;
@ -102,7 +85,6 @@ public class startMultiplayerGame extends JPanel {
}
});
// Um das Semester zu senken.
semesterDownButton.addActionListener(e -> {
if (semesterCounter > 1) {
semesterCounter--;
@ -110,122 +92,38 @@ public class startMultiplayerGame extends JPanel {
}
});
// Um Player nach links zu "rotieren".
// PLAYERTOGGLEBUTTONS
PlayerLeftButton.addActionListener(e -> {
togglePlayerIconLeft();
toggleLeftPlayerIcon();
updateTextFields();
});
// Um Player nach rechts zu "rotieren".
PlayerRightButton.addActionListener(e -> {
togglePlayerIconRight();
toggleLeftPlayerIcon();
updateTextFields();
});
// Um Namen des linken Spielers zu speichern.
PlayerTextField.addActionListener(e -> {
PlayerNickname = PlayerTextField.getText();
System.out.println("Linker Spielername geändert zu: " + PlayerNickname); // Debugging-Ausgabe
});
// ActionListener für den "Back" Button, um zum vorherigen Panel zurückzukehren
// 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
backButton.addActionListener(e -> frame.showPanel("MainMenu"));
joinGameButton.addActionListener(e -> frame.showPanelSMG("JoinGame",1));
createGameButton.addActionListener(e -> frame.showPanelSMG("JoinGame",0));
}
});
// 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) {
// TOGGLE METHODEN
private void toggleLeftPlayerIcon() {
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) {
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);
}
}
});
}
// Hilfsfunktionen
/**
* Setzt das jeweils "nächste" Icon, wenn der PlayerLeftButton gedrückt wird.
* @author Joshua Kuklok
*/
private void togglePlayerIconLeft() {
if (PlayerIcon.getIcon() == humanPlayerIcon) {
PlayerIcon.setIcon(aiPlayerHardIcon);
} else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){
PlayerIcon.setIcon(humanPlayerIcon);
} else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) {
PlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (PlayerIcon.getIcon() == aiPlayerHardIcon) {
PlayerIcon.setIcon(aiPlayerNormalIcon);
}
}
/**
* Setzt das jeweils "nächste" Icon, wenn der PlayerRightButton gedrückt wird.
* @author Joshua Kuklok
*/
private void togglePlayerIconRight() {
if (PlayerIcon.getIcon() == humanPlayerIcon) {
PlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){
PlayerIcon.setIcon(aiPlayerNormalIcon);
} else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) {
PlayerIcon.setIcon(aiPlayerHardIcon);
} else if (PlayerIcon.getIcon() == aiPlayerHardIcon) {
PlayerIcon.setIcon(aiPlayerIcon);
} else {
PlayerIcon.setIcon(humanPlayerIcon);
}
}
/**
* Aktualisiert die Textfelder basierend auf den Icons
* @author Joshua Kuklok
*/
private void updateTextFields() {
if (PlayerIcon.getIcon() == humanPlayerIcon) {
PlayerTextField.setText(PlayerNickname);
} else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){
PlayerTextField.setText("Einfach");
} else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) {
PlayerTextField.setText("Mittel");
} else if (PlayerIcon.getIcon() == aiPlayerHardIcon) {
PlayerTextField.setText("Schwer");
} else {
PlayerTextField.setText("Leicht");
}
}
}