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 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, 30 + 20 * i, 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); 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 } } } delay(30); lastT = System.nanoTime(); // delta time frame.setVisible(true); // ----------------------------------------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------------------------------------- while (true) { // Hauptschleife for (int i = 0; i < ghosts.length; i++) { if (ghosts[i].getIsDead()) { if (ghosts[i].getDeathTimer() != 0) { ghosts[i].setDeathTimer(ghosts[i].getDeathTimer() - 1); // System.out.println(ghosts[i].getDeathTimer()); } else { ghosts[i].setIsDead(false); ghosts[i].setPos('x', Map.ghost_posX[i]); ghosts[i].setPos('y', Map.ghost_posY[i]); } } } frames++; 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 // Zu Beginn jeden Schleifendurchlaufs wird die Position von Pac-Man neu // gesetzt: 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]; } } // System.out.println(HCost[0] + " " + HCost[1] + " " + HCost[2] + " " + // HCost[3]); 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; } } } } } for (int i = 0; i < 35; i++) { for (int j = 0; j < 35; j++) { 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)); } } } } for (int i = 0; i < 35; i++) { for (int j = 0; j < 35; j++) { 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; } } } } } player.calcDir(0); // Berechnen wo Pac-Man als nächstes hin soll for (int i = 0; i < ghosts.length; i++) { ghosts[i].setLocation(ghosts[i].getPos('x', dt), ghosts[i].getPos('y', dt)); if (player.getPos('x', 0) < ghosts[i].getPos('x', 0) + 20 && player.getPos('x', 0) > ghosts[i].getPos('x', 0) - 20 && player.getPos('y', 0) < ghosts[i].getPos('y', 0) + 20 && player.getPos('y', 0) > ghosts[i].getPos('y', 0) - 20) if (ghosts[0].feared) { ghosts[i].setIsDead(true); ghosts[i].setDeathTimer(1000); ghosts[i].setPos('x', -100); ghosts[i].setPos('y', -100); score += 1000; System.out.println("Geist" + i + " ist gestorben" + ghosts[i].getIsDead()); } 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; } } fps = 1000000000 / dt; // System.out.println("fps: " + fps); delay(delaytimer); // 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); } } } } // 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; } }