Pac-Man/src/Game.java

495 lines
15 KiB
Java

import java.awt.Color;
import java.awt.Font;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
// In dieser Klasse findet der größte Teil des Spiels statt:
// Rendern von Map, Geistern, Pac-Man etc.
// Überprüfung von Kollisionen verschiedener Elemente (der komplizierteste Teil des Programms)
public class Game {
// Deklaration der sichtbaren Elemente
JFrame frame;
JPanel panel;
Player player;
Ghost ghosts[];
Map map;
// Delta time: siehe https://en.wikipedia.org/wiki/Delta_timing
private long dt;
private long lastT;
private int score = 0;
private JLabel scoreLabel;
private JLabel fpsLabel;
private JLabel liveLabels[];
private int delaytimer = 4;
@SuppressWarnings("unused")
private long fps = 60;
private int windowSizeX = 880; // Größe des Frame in x-Richtung
private int windowSizeY = 800; // Größe des Frame in y-Richtung
private int frameLocationX = 100; // Position des Frame auf dem Bildschirm in x-Richtung
private int frameLocationY = 100; // Position des Frame auf dem Bildschirm in x-Richtung
// oben links (0|0)
// nach rechts --> x wird größer
// nach unten --> y wird größer
public static int frames;
int minn;
int[] HCost = new int[4];
public Game(String selectedMap) { // Erstellen des Konstruktors (Was soll passieren, sobald dieses Klasse
// aufgerufen wird?)
frame = new JFrame(); // Fenster
ImageIcon img = new ImageIcon("assets/Pacman_Right.png");
frame.setIconImage(img.getImage());
panel = new JPanel(); // darauf werden alle sichtbaren Elemente gespeichert
ghosts = new Ghost[4]; // 4 Geister
boolean[][] ghost_possible = new boolean[ghosts.length][4];
player = new Player(); // Pac-Man
liveLabels = new JLabel[3];
for (int i = 0; i < liveLabels.length; i++) {
liveLabels[i] = new Lives();
panel.add(liveLabels[i]);
liveLabels[i].setBounds(710 + 20 * i, 35 , 20, 20);
}
scoreLabel = new JLabel(Integer.toString(score));
panel.add(scoreLabel);
scoreLabel.setForeground(Color.WHITE);
scoreLabel.setBounds(710, 0, 500, 50);
Font f = new Font("Consolas", Font.BOLD, 24);
scoreLabel.setFont(f);
fpsLabel = new JLabel(Integer.toString(score));
panel.add(fpsLabel);
fpsLabel.setForeground(Color.WHITE);
fpsLabel.setBounds(710, 45, 500, 50);
fpsLabel.setFont(f);
panel.add(player); // Pac-Man wird dem Panel hinzugefügt
frame.addKeyListener(player); // KeyListener wird hinzugefügt, man kann nun Pac-Maan mit der tastatur steuern
// Einstellen des Frame bezüglich Größe und Position
frame.setSize(windowSizeX, windowSizeY);
frame.setLocation(frameLocationX, frameLocationY);
frame.setVisible(false);
frame.setTitle("Pac-Man"); // Der Titel des Frame wird auf "Pac-Man" gesetzt
frame.setResizable(false); // Man kann die Größe des Frame nicht verändern
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Wenn der Frame geschlossen wird, wird auch das Programm
// beendet
// Der Inhalt des Panels wird auf dem Frame angezeigt:
frame.setContentPane(panel);
frame.getContentPane().setLayout(null);
panel.setBackground(Color.BLACK); // Der Hintergrund ist schwarz
for (int i = 0; i < ghosts.length; i++) { // für jeden Geist:
ghosts[i] = new Ghost(i); // Erstellen des jeweiligen Geistes
panel.add(ghosts[i]); // Hinzufügen zum Panel des jeiligen Geistes
ghosts[i].setBounds(ghosts[i].getPos('x', 0), ghosts[i].getPos('y', 0), 20, 20);
}
map = new Map(selectedMap, player, ghosts); // Map auf der gespielt wird
map.mapping();
player.setBounds(player.getPos('x', 0), player.getPos('y', 0), 20, 20); // Pac-Man wird das erste Mal gerendert
for (int i = 0; i < 35; i++) { // für jeden Brick
for (int j = 0; j < 35; j++) { // für jeden Brick
if (Map.bricks[j][i] != null) { // Damit kein Fehler auftritt wegen nicht vorhandenen Bricks
panel.add(Map.bricks[j][i]); // Der jeweilige Brick wird zum panel hinzugefügt
Map.bricks[j][i].setBounds(Map.bricks[j][i].xPos, Map.bricks[j][i].yPos, 20, 20); // Rendern des
}
}
}
for (int i = 0; i < 35; i++) { // für jeden Brick // points
for (int j = 0; j < 35; j++) { // für jeden Brick
if (Map.points[j][i] != null) { // Damit kein Fehler auftritt wegen nicht vorhandenen Bricks
panel.add(Map.points[j][i]); // Der jeweilige Brick wird zum panel hinzugefügt
Map.points[j][i].setBounds(Map.points[j][i].xPos, Map.points[j][i].yPos, 20, 20); // Rendern des
}
}
}
for (int i = 0; i < 35; i++) { // für jeden Brick // points
for (int j = 0; j < 35; j++) { // für jeden Brick
if (Map.bigpoints[j][i] != null) { // Damit kein Fehler auftritt wegen nicht vorhandenen Bricks
panel.add(Map.bigpoints[j][i]); // Der jeweilige Brick wird zum panel hinzugefügt
Map.bigpoints[j][i].setBounds(Map.bigpoints[j][i].xPos, Map.bigpoints[j][i].yPos, 20, 20); // Rendern
// des
}
}
}
if (Map.Left != null && Map.Right != null) {
panel.add(Map.Left);
panel.add(Map.Right);
Map.Left.setBounds(Map.Left.xPos, Map.Left.yPos, 20, 20);
Map.Right.setBounds(Map.Right.xPos, Map.Right.yPos, 20, 20);
}
lastT = System.nanoTime(); // delta time
delay(1000);
frame.setVisible(true);
// -----------------------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------------------
while (true) { // Hauptschleife
if (ghosts[0].feared == true) {
if (Ghost.fearedTimer != 0) {
Ghost.fearedTimer--;
} else {
for (int i = 0; i < ghosts.length; i++) {
ghosts[i].feared = false;
ghosts[i].ogSauce();
Ghost.offFrames = 4;
}
}
}
dt = System.nanoTime() - lastT; // delta time
lastT = System.nanoTime(); // delta time
player.setLocation(player.getPos('x', dt), player.getPos('y', dt));
for (int i = 0; i < ghosts.length; i++) {
if (!ghosts[i].getIsDead()) {
ghost_possible[i][0] = false;
ghost_possible[i][1] = false;
ghost_possible[i][2] = false;
ghost_possible[i][3] = false;
if ((Map.bricks[conv(ghosts[i].yPos)][conv(ghosts[i].xPos) + 1] == null
&& Map.bricks[conv(ghosts[i].yPos + 19)][conv(ghosts[i].xPos) + 1] == null)
|| (ghosts[i].xPos + 10) % 20 != 0) {
ghost_possible[i][0] = true;
}
if ((Map.bricks[conv(ghosts[i].yPos)][conv(ghosts[i].xPos) - 1] == null
&& Map.bricks[conv(ghosts[i].yPos + 19)][conv(ghosts[i].xPos) - 1] == null)
|| (ghosts[i].xPos + 10) % 20 != 0) {
ghost_possible[i][1] = true;
}
if ((Map.bricks[conv(ghosts[i].yPos) - 1][conv(ghosts[i].xPos)] == null
&& Map.bricks[conv(ghosts[i].yPos) - 1][conv(ghosts[i].xPos + 19)] == null)
|| (ghosts[i].yPos + 10) % 20 != 0) {
ghost_possible[i][2] = true;
}
if ((Map.bricks[conv(ghosts[i].yPos) + 1][conv(ghosts[i].xPos)] == null
&& Map.bricks[conv(ghosts[i].yPos) + 1][conv(ghosts[i].xPos + 19)] == null)
|| (ghosts[i].yPos + 10) % 20 != 0) {
ghost_possible[i][3] = true;
}
HCost[0] = ghosts[i].getHCost(player, 1, 0);
HCost[1] = ghosts[i].getHCost(player, -1, 0);
HCost[2] = ghosts[i].getHCost(player, 0, -1);
HCost[3] = ghosts[i].getHCost(player, 0, 1);
//
int minn = 10000;
if (ghosts[i].dire == 2) {
HCost[3] = 10000;
}
if (ghosts[i].dire == 3) {
HCost[2] = 10000;
}
if (ghosts[i].dire == 1) {
HCost[0] = 10000;
}
if (ghosts[i].dire == 0) {
HCost[1] = 10000;
}
for (int j = 0; j < 4; j++) {
if (ghost_possible[i][j] == false) {
HCost[j] = 10500;
}
}
for (int j = 0; j < 4; j++) {
if (minn > HCost[j]) {
minn = HCost[j];
}
}
for (int j = 0; j < 4; j++) {
if (HCost[j] == minn) {
if (frames % Ghost.offFrames == 0) {
if (j == 0) {
ghosts[i].right = true;
ghosts[i].left = false;
ghosts[i].down = false;
ghosts[i].up = false;
ghosts[i].dire = 0;
break;
}
if (j == 1) {
ghosts[i].left = true;
ghosts[i].right = false;
ghosts[i].down = false;
ghosts[i].up = false;
ghosts[i].dire = 1;
break;
}
if (j == 2) {
ghosts[i].up = true;
ghosts[i].right = false;
ghosts[i].left = false;
ghosts[i].down = false;
ghosts[i].dire = 2;
break;
}
if (j == 3) {
ghosts[i].down = true;
ghosts[i].right = false;
ghosts[i].left = false;
ghosts[i].up = false;
ghosts[i].dire = 3;
break;
}
}
}
}
}
}
// Kollision von Pac-Man mit Bricks:
for (int i = 0; i < 35; i++) { // für jeden Brick
for (int j = 0; j < 35; j++) { // für jeden Brick
if (Map.bricks[j][i] != null) { // Damit kein Fehler auftritt wegen nicht vorhandenen Bricks
if (player.getPos('x', 0) < Map.bricks[j][i].xPos + 20
&& player.getPos('x', 0) > Map.bricks[j][i].xPos - 20
&& player.getPos('y', 0) < Map.bricks[j][i].yPos + 20
&& player.getPos('y', 0) > Map.bricks[j][i].yPos - 20) {
if (player.left) {
player.setPos('x', Map.bricks[j][i].xPos + 20);
player.setPos('y', Map.bricks[j][i].yPos);
player.left = false;
} else if (player.right) {
player.setPos('x', Map.bricks[j][i].xPos - 20);
player.setPos('y', Map.bricks[j][i].yPos);
player.right = false;
} else if (player.up) {
player.setPos('y', Map.bricks[j][i].yPos + 20);
player.setPos('x', Map.bricks[j][i].xPos);
player.up = false;
} else if (player.down) {
player.setPos('y', Map.bricks[j][i].yPos - 20);
player.setPos('x', Map.bricks[j][i].xPos);
player.down = false;
}
}
}
if (Map.points[j][i] != null) {
if (player.getPos('x', 0) < Map.points[j][i].xPos + 5
&& player.getPos('x', 0) > Map.points[j][i].xPos - 5
&& player.getPos('y', 0) < Map.points[j][i].yPos + 5
&& player.getPos('y', 0) > Map.points[j][i].yPos - 5) {
Map.points[j][i].setBounds(0, 0, 0, 0);
Map.points[j][i] = null;
score += 150;
scoreLabel.setText(Integer.toString(score));
}
}
if (Map.bigpoints[j][i] != null) {
if (player.getPos('x', 0) < Map.bigpoints[j][i].xPos + 6
&& player.getPos('x', 0) > Map.bigpoints[j][i].xPos - 6
&& player.getPos('y', 0) < Map.bigpoints[j][i].yPos + 6
&& player.getPos('y', 0) > Map.bigpoints[j][i].yPos - 6) {
Map.bigpoints[j][i].setBounds(0, 0, 0, 0);
Map.bigpoints[j][i] = null;
score += 1000;
scoreLabel.setText(Integer.toString(score));
for (i = 0; i < 4; i++) {
ghosts[i].feared = true;
Ghost.fearedTimer = 1000;
ghosts[i].changeSauce("feared");
if (ghosts[i].left) {
ghosts[i].dire = 0;
} else if (ghosts[i].right) {
ghosts[i].dire = 1;
} else if (ghosts[i].down) {
ghosts[i].dire = 3;
} else if (ghosts[i].up) {
ghosts[i].dire = 4;
}
Ghost.offFrames = 6;
}
}
}
}
}
if (Map.Left != null) {
if (player.getPos('x', 0) < Map.Left.xPos + 20 && player.getPos('x', 0) > Map.Left.xPos - 20
&& player.getPos('y', 0) < Map.Left.yPos + 20 && player.getPos('y', 0) > Map.Left.yPos - 20) {
if (Map.Right != null) {
player.xPos = Map.Right.xPos - 20;
player.yPos = Map.Right.yPos;
}
}
}
if (Map.Right != null) {
if (player.getPos('x', 0) < Map.Right.xPos + 20 && player.getPos('x', 0) > Map.Right.xPos - 20
&& player.getPos('y', 0) < Map.Right.yPos + 20 && player.getPos('y', 0) > Map.Right.yPos - 20) {
if (Map.Left != null) {
player.xPos = Map.Left.xPos + 20;
player.yPos = Map.Left.yPos;
}
}
}
// Geister LOOP
for (int i = 0; i < ghosts.length; i++) {
//
if (ghosts[i].getIsDead()) {
if (ghosts[i].getDeathTimer() != 0) {
ghosts[i].setDeathTimer(ghosts[i].getDeathTimer() - 1);
} else {
ghosts[i].setIsDead(false);
ghosts[i].setPos('x', Map.ghost_posX[i]);
ghosts[i].setPos('y', Map.ghost_posY[i]);
}
}
ghosts[i].setLocation(ghosts[i].getPos('x', dt), ghosts[i].getPos('y', dt));
if (player.getPos('x', 0) < ghosts[i].getPos('x', 0) + 18
&& player.getPos('x', 0) > ghosts[i].getPos('x', 0) - 18
&& player.getPos('y', 0) < ghosts[i].getPos('y', 0) + 14
&& player.getPos('y', 0) > ghosts[i].getPos('y', 0) - 14)
if (ghosts[0].feared) {
ghosts[i].setIsDead(true);
ghosts[i].setDeathTimer(1000);
ghosts[i].setPos('x', -100);
ghosts[i].setPos('y', -100);
score += 1000;
} else {
player.lives--;
liveLabels[player.lives].setBounds(0, 0, 0, 0);
if (player.lives == 0) {
System.exit(0);
}
delay(200);
for (int j = 0; j < ghosts.length; j++) {
ghosts[j].setPos('x', Map.ghost_posX[j]);
ghosts[j].setPos('y', Map.ghost_posY[j]);
}
player.setPos('x', Map.pac_posX);
player.setPos('y', Map.pac_posY);
player.up = false;
player.down = false;
player.right = false;
player.left = false;
}
// Geister LOOP
}
//
// Ein delay zum Ende der Hauptschleife
if (frames % 100 == 0) {
boolean empty = true;
for (int i = 0; i < 35; i++) {
for (int j = 0; j < 35; j++) {
if (Map.points[j][i] != null) {
empty = false;
}
}
}
for (int i = 0; i < 35; i++) {
for (int j = 0; j < 35; j++) {
if (Map.bigpoints[j][i] != null) {
empty = false;
}
}
}
if (empty) {
scoreLabel.setText("YOU WON");
delay(1000);
System.exit(0); // HIER DEN HIGHSCORE IMPLEMENTIEREN
}
}
player.calcDir(0); // Berechnen wo Pac-Man als nächstes hin soll
fps = 1000000000 / dt;
fpsLabel.setText("fps: " + Integer.toString((int) fps));
frames++; // FRAMES WIRD HOCHGESETZT
delay(delaytimer);
//
}
// ENDE DER WHILE-SCHLEIFE
}
// Methode zum verzögern (warten) in ms
public void delay(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private int conv(float a) { // 90.0 --> 4
int b = (int) (a - 10) / 20;
return b;
}
}