255 lines
9.7 KiB
Java
255 lines
9.7 KiB
Java
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 Jeweiliger Button der hinzugefügt werden soll
|
|
* @author Joshua Kuklok
|
|
*/
|
|
public void addShipButton(ShipButton button) {
|
|
shipButtonList.add(button);
|
|
paintFields();
|
|
}
|
|
|
|
/**
|
|
* Gibt currentShip zurück
|
|
* @return currentShip Objekt der Klasse Schiff
|
|
* @author Lucas Bronson Luca Conte
|
|
*/
|
|
public Ship getCurrentShip() {
|
|
return currentShip;
|
|
}
|
|
|
|
/**
|
|
* Konstruktor des Board Displays
|
|
* @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 für überspringen von Rahmenzeile-/spalte
|
|
final int y = i - 1; // Temporäre Variable für überspringen von Rahmenzeile-/spalte
|
|
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("Roboto", 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);
|
|
}
|
|
if (player == null || player.getBoard() == null) return;
|
|
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.WHITE);
|
|
}
|
|
}
|
|
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();
|
|
}
|
|
}
|