You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
7.5 KiB
268 lines
7.5 KiB
package de.tims.fleetstorm.gui;
|
|
|
|
import java.awt.BorderLayout;
|
|
import java.awt.Color;
|
|
import java.awt.Font;
|
|
import java.awt.event.MouseAdapter;
|
|
import java.awt.event.MouseEvent;
|
|
import java.util.ArrayList;
|
|
|
|
import javax.swing.JFrame;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.SwingConstants;
|
|
import javax.swing.border.MatteBorder;
|
|
|
|
import de.tims.fleetstorm.ai.Logic;
|
|
import de.tims.fleetstorm.matchfield.Coordinate;
|
|
import de.tims.fleetstorm.matchfield.Matchfield;
|
|
|
|
public class GameLogic extends JPanel {
|
|
|
|
// GameManager stuff
|
|
private int gameState;
|
|
private Matchfield matchfield;
|
|
private Matchfield enemyMatchfield;
|
|
private int matchfieldSize = 10;
|
|
private boolean playerMove;
|
|
private Logic aiLogic;
|
|
|
|
public static final int PREPARATION = 1;
|
|
public static final int RUNNING = 2;
|
|
public static final int GAME_OVER = 3;
|
|
|
|
// GUI stuff
|
|
private ArrayList<JPanel> playerFields;
|
|
private ArrayList<JPanel> enemyFields;
|
|
|
|
public GameLogic(int gapToFrameBorderX, int gapToFrameBorderY, int fieldWidth, int spaceBetween) {
|
|
this.playerFields = new ArrayList<>();
|
|
this.enemyFields = new ArrayList<>();
|
|
|
|
setSize(640, 480);
|
|
|
|
fieldWrapper = new JPanel();
|
|
fieldWrapper.setBounds(10, 11, 305, 458);
|
|
fieldWrapper.setLayout(null);
|
|
setLayout(null);
|
|
add(fieldWrapper);
|
|
|
|
enemyFieldWrapper = new JPanel();
|
|
enemyFieldWrapper.setLayout(null);
|
|
enemyFieldWrapper.setBounds(326, 11, 305, 458);
|
|
add(enemyFieldWrapper);
|
|
|
|
this.generateFieldsForGUI(gapToFrameBorderX, gapToFrameBorderY, fieldWidth, spaceBetween, fieldWrapper,
|
|
this.playerFields, false);
|
|
|
|
JLabel ownFieldLabel = new JLabel("Eigenes Spielfeld");
|
|
ownFieldLabel.setBounds(10, 11, 114, 14);
|
|
fieldWrapper.add(ownFieldLabel);
|
|
this.generateFieldsForGUI(gapToFrameBorderX, gapToFrameBorderY, fieldWidth, spaceBetween, enemyFieldWrapper,
|
|
this.enemyFields, true);
|
|
|
|
JLabel enemyFieldLabel = new JLabel("Gegnerisches Spielfeld");
|
|
enemyFieldLabel.setBounds(10, 11, 168, 14);
|
|
enemyFieldWrapper.add(enemyFieldLabel);
|
|
}
|
|
|
|
private void generateFieldsForGUI(int gapToFrameBorderX, int gapToFrameBorderY, int fieldWidth, int spaceBetween,
|
|
JPanel panel, ArrayList<JPanel> fields, boolean registerMouseListener) {
|
|
|
|
for (int x = 0; x < this.matchfieldSize; x++) {
|
|
for (int y = 0; y < this.matchfieldSize; y++) {
|
|
JPanel field = new JPanel();
|
|
|
|
int xPos = gapToFrameBorderX + x * fieldWidth + (x * spaceBetween);
|
|
int yPos = gapToFrameBorderY + y * fieldWidth + (y * spaceBetween);
|
|
|
|
field.setBounds(xPos, yPos, fieldWidth, fieldWidth);
|
|
field.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
|
|
field.setName(x + ":" + y);
|
|
|
|
fields.add(field);
|
|
panel.add(field);
|
|
|
|
if (!registerMouseListener)
|
|
continue;
|
|
|
|
field.addMouseListener(new MouseAdapter() {
|
|
|
|
public void mouseClicked(MouseEvent e) {
|
|
int[] coords = getCoordinateFromLabel(field);
|
|
int coordX = coords[0];
|
|
int coordY = coords[1];
|
|
|
|
Coordinate chosenField = enemyMatchfield.getField(coordX, coordY);
|
|
|
|
boolean shotSuccess = chosenField.shoot();
|
|
|
|
boolean areAllShipsHit = enemyMatchfield.areAllShipsHit();
|
|
if (areAllShipsHit) {
|
|
gameOver(true);
|
|
return;
|
|
}
|
|
|
|
if (shotSuccess && chosenField.getState() != Coordinate.HIT) {
|
|
nextMove(false);
|
|
} else {
|
|
nextMove(true);
|
|
}
|
|
|
|
}
|
|
});
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
private JLabel getXLabel() {
|
|
JLabel x = new JLabel("x");
|
|
x.setForeground(Color.WHITE);
|
|
return x;
|
|
}
|
|
|
|
private int[] getCoordinateFromLabel(JPanel panel) {
|
|
String panelName = panel.getName();
|
|
String[] panelNameSplit = panelName.split(":");
|
|
int coordX = Integer.parseInt(panelNameSplit[0]);
|
|
int coordY = Integer.parseInt(panelNameSplit[1]);
|
|
return new int[] { coordX, coordY };
|
|
}
|
|
|
|
private void updateFields() {
|
|
this.updateField(enemyMatchfield, this.enemyFields);
|
|
this.updateField(matchfield, this.playerFields);
|
|
}
|
|
|
|
private void updateField(Matchfield matchfield, ArrayList<JPanel> fields) {
|
|
|
|
for (JPanel coordinatePanel : fields) {
|
|
int[] coords = getCoordinateFromLabel(coordinatePanel);
|
|
int coordX = coords[0];
|
|
int coordY = coords[1];
|
|
|
|
// reset field
|
|
coordinatePanel.setBackground(null);
|
|
coordinatePanel.removeAll();
|
|
|
|
int state = matchfield.getField(coordX, coordY).getState();
|
|
|
|
switch (state) {
|
|
case Coordinate.SHIP:
|
|
if (playerMove)
|
|
coordinatePanel.setBackground(new Color(91, 58, 41));
|
|
break;
|
|
case Coordinate.SHOT:
|
|
coordinatePanel.setBackground(new Color(0, 94, 184));
|
|
break;
|
|
case Coordinate.HIT:
|
|
coordinatePanel.setBackground(new Color(91, 58, 41));
|
|
coordinatePanel.add(getXLabel());
|
|
break;
|
|
}
|
|
|
|
coordinatePanel.revalidate();
|
|
coordinatePanel.repaint();
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* This function is only for testing
|
|
*/
|
|
private static GameLogic gui;
|
|
private JPanel fieldWrapper;
|
|
private JPanel enemyFieldWrapper;
|
|
|
|
public static void main(String[] args) {
|
|
JFrame frame = new JFrame("Test GUI");
|
|
gui = new GameLogic(12, 35, 25, 1);
|
|
frame.setContentPane(gui);
|
|
frame.setSize(640, 480);
|
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
frame.setResizable(true);
|
|
frame.setVisible(true);
|
|
|
|
gui.start(false);
|
|
}
|
|
|
|
public void start(boolean test) {
|
|
this.gameState = GameLogic.PREPARATION;
|
|
this.playerMove = true;
|
|
|
|
// create player matchfield and set ships
|
|
this.matchfield = new Matchfield(matchfieldSize);
|
|
this.matchfield.createMatchfield();
|
|
this.matchfield.setShipOnRandomPosition(2);
|
|
this.matchfield.setShipOnRandomPosition(3);
|
|
this.matchfield.setShipOnRandomPosition(4);
|
|
this.matchfield.setShipOnRandomPosition(5);
|
|
|
|
this.aiLogic = new Logic();
|
|
this.aiLogic.setMatchfield(this.matchfield);
|
|
|
|
// create enemy matchfield, set ships and initialize AI (with player's
|
|
// matchfield)
|
|
this.enemyMatchfield = new Matchfield(matchfieldSize);
|
|
this.enemyMatchfield.createMatchfield();
|
|
this.enemyMatchfield.setShipOnRandomPosition(2);
|
|
this.enemyMatchfield.setShipOnRandomPosition(3);
|
|
this.enemyMatchfield.setShipOnRandomPosition(4);
|
|
this.enemyMatchfield.setShipOnRandomPosition(5);
|
|
|
|
// enter game loop
|
|
this.gameState = GameLogic.RUNNING;
|
|
if (!test)
|
|
this.nextMove(true);
|
|
}
|
|
|
|
public void nextMove(boolean playerMove) {
|
|
this.playerMove = playerMove;
|
|
|
|
if (this.playerMove) {
|
|
gui.updateFields();
|
|
// waiting here for mouse click event....
|
|
} else {
|
|
|
|
Coordinate aiChosenField = null;
|
|
while (aiChosenField == null) {
|
|
aiChosenField = this.aiLogic.chooseField();
|
|
}
|
|
|
|
aiChosenField.shoot();
|
|
|
|
gui.updateFields();
|
|
|
|
boolean areAllShipsHit = this.matchfield.areAllShipsHit();
|
|
if (areAllShipsHit) {
|
|
this.gameOver(false);
|
|
return;
|
|
}
|
|
|
|
boolean aiHasNextMove = aiChosenField.getState() != Coordinate.HIT;
|
|
this.nextMove(aiHasNextMove);
|
|
}
|
|
|
|
}
|
|
|
|
protected void gameOver(boolean playerWinner) {
|
|
this.gameState = GameLogic.GAME_OVER;
|
|
|
|
this.removeAll();
|
|
this.setLayout(new BorderLayout());
|
|
|
|
JLabel wonLabel = new JLabel(playerWinner ? "Du hast gewonnen!" : "Du hast verloren!");
|
|
wonLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
|
wonLabel.setVerticalAlignment(SwingConstants.CENTER);
|
|
wonLabel.setFont(new Font("Tahoma", Font.BOLD, 18));
|
|
this.add(wonLabel, SwingConstants.CENTER);
|
|
|
|
this.revalidate();
|
|
this.repaint();
|
|
}
|
|
|
|
public int getGameState() {
|
|
return gameState;
|
|
}
|
|
}
|