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

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;
}
}