Letzte Übung :)
parent
dc7510f715
commit
666f0ac6aa
|
|
@ -0,0 +1,21 @@
|
||||||
|
package Uebung_05_Andres;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
public class Design {
|
||||||
|
// Konstante für die Bildschirmbreite
|
||||||
|
public static final int SCREEN_WIDTH = 400;
|
||||||
|
// Konstante für die Bildschirmhöhe
|
||||||
|
public static final int SCREEN_HEIGHT = 400;
|
||||||
|
// Konstante für die Größe eines Feldes des Labyrinths
|
||||||
|
public static final int CELL_SIZE = 40;
|
||||||
|
// Definierte Farben für das Spiel
|
||||||
|
public static final Color YELLOW = new Color(255, 255, 0);
|
||||||
|
public static final Color RED = new Color(255, 0, 0);
|
||||||
|
public static final Color WHITE = new Color(255, 255, 255);
|
||||||
|
public static final Color BLUE = new Color(0, 0, 255);
|
||||||
|
public static final Color BLACK = new Color(0, 0, 0);
|
||||||
|
public static final Color GREEN = new Color(0, 100, 0);
|
||||||
|
public static final Color ORANGE = new Color(255, 140, 0);
|
||||||
|
public static final Color PINK = new Color(255, 192, 203);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
package Uebung_05_Andres;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
|
||||||
|
import javax.swing.Timer;
|
||||||
|
|
||||||
|
public class Ghost {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
boolean isEatable;
|
||||||
|
|
||||||
|
private Color color;
|
||||||
|
private final Color EATABLE_COLOR = Design.BLUE;
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
// Konstruktor für den Geist
|
||||||
|
public Ghost(int x, int y, Color color) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.color = color;
|
||||||
|
this.isEatable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void makeGhostEatable() {
|
||||||
|
//Extend duration if pacman eats multiple power pills quickly
|
||||||
|
if (isEatable) {
|
||||||
|
timer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isEatable = true;
|
||||||
|
|
||||||
|
// After 10 seconds, set isEatable to false
|
||||||
|
timer = new Timer(10000, e -> {
|
||||||
|
this.isEatable = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
timer.setRepeats(false); // This ensures the timer only runs once
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void gotEaten() {
|
||||||
|
this.isEatable = false;
|
||||||
|
//Teleport ghost to ghost-box
|
||||||
|
this.x = 9;
|
||||||
|
this.y = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zeichne den Geist
|
||||||
|
public void draw(Graphics g) {
|
||||||
|
g.setColor(isEatable ? EATABLE_COLOR : color);
|
||||||
|
String[] ghostPixels = {
|
||||||
|
" #### ",
|
||||||
|
"######",
|
||||||
|
"## # #",
|
||||||
|
"######",
|
||||||
|
"######",
|
||||||
|
"# # # "
|
||||||
|
};
|
||||||
|
int pixelSize = Design.CELL_SIZE / ghostPixels.length;
|
||||||
|
for (int rowIdx = 0; rowIdx < ghostPixels.length; rowIdx++) {
|
||||||
|
for (int colIdx = 0; colIdx < ghostPixels[rowIdx].length(); colIdx++) {
|
||||||
|
if (ghostPixels[rowIdx].charAt(colIdx) == '#') {
|
||||||
|
int pixelX = x * Design.CELL_SIZE + colIdx * pixelSize;
|
||||||
|
int pixelY = y * Design.CELL_SIZE + rowIdx * pixelSize;
|
||||||
|
g.fillRect(pixelX, pixelY, pixelSize, pixelSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package Uebung_05_Andres;
|
||||||
|
|
||||||
|
import java.awt.Graphics;
|
||||||
|
|
||||||
|
public class Pacman {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
// Konstruktor für Pacman
|
||||||
|
public Pacman(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zeichne Pacman
|
||||||
|
public void draw(Graphics g) {
|
||||||
|
g.setColor(Design.YELLOW);
|
||||||
|
|
||||||
|
// Angle for the mouth (for animation)
|
||||||
|
int startAngle = (int)(Math.sin(System.currentTimeMillis() / 200.0) * 45); // Animating the mouth to open and close
|
||||||
|
int arcAngle = 270 - startAngle * 2; // The size of the mouth opening
|
||||||
|
|
||||||
|
// Draw Pac-Man with an open mouth
|
||||||
|
g.fillArc(
|
||||||
|
x * Design.CELL_SIZE,
|
||||||
|
y * Design.CELL_SIZE,
|
||||||
|
Design.CELL_SIZE,
|
||||||
|
Design.CELL_SIZE,
|
||||||
|
startAngle + 30,
|
||||||
|
arcAngle + 30
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,272 @@
|
||||||
|
package Uebung_05_Andres;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
// Hauptklasse für das Pacman-Spiel
|
||||||
|
public class PacmanGame extends JPanel implements KeyListener, ActionListener {
|
||||||
|
// Timer für das Fortschreiten des Spiels
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Labyrinth definition:
|
||||||
|
* # -> wall
|
||||||
|
* * -> power pill
|
||||||
|
* / -> teleportation point
|
||||||
|
* . -> cookie
|
||||||
|
* _ -> empty space for practical purposes
|
||||||
|
*/
|
||||||
|
private String[] labyrinth = {
|
||||||
|
"###################",
|
||||||
|
"#..........##....*#",
|
||||||
|
"#.##.###.#.##.###.#",
|
||||||
|
"#.##.#............#",
|
||||||
|
"#*...#.##-##.#.#..#",
|
||||||
|
"##.#....# #..#.#.##",
|
||||||
|
"##.#.##.###.##.#.##",
|
||||||
|
"/_.#.##..*..##.#._/",
|
||||||
|
"##.#....###....#.##",
|
||||||
|
"##.#############.##",
|
||||||
|
"#.................#",
|
||||||
|
"#.###.##...##.###.#",
|
||||||
|
"#.###....#....###.#",
|
||||||
|
"#.....##.*.##.....#",
|
||||||
|
"###################"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Anzahl der Zeilen und Spalten im Labyrinth
|
||||||
|
private int ROWS = labyrinth.length;
|
||||||
|
private int COLS = labyrinth[0].length();
|
||||||
|
|
||||||
|
// Referenzen für Pacman und einen Geist
|
||||||
|
private Pacman pacman;
|
||||||
|
private Ghost[] ghosts = new Ghost[4];
|
||||||
|
|
||||||
|
// Konstruktor für das Pacman-Spiel
|
||||||
|
public PacmanGame() {
|
||||||
|
// Setze Dimensionen des Spielfelds
|
||||||
|
setPreferredSize(new Dimension(COLS * Design.CELL_SIZE, ROWS * Design.CELL_SIZE));
|
||||||
|
// Setze Hintergrundfarbe
|
||||||
|
setBackground(Design.BLACK);
|
||||||
|
// Füge KeyListener hinzu
|
||||||
|
addKeyListener(this);
|
||||||
|
// Ermögliche die Fokussierung auf das JPanel
|
||||||
|
setFocusable(true);
|
||||||
|
|
||||||
|
// Initialisiere Pacman und Geist
|
||||||
|
pacman = new Pacman(1, 1);
|
||||||
|
ghosts[0] = new Ghost(1, ROWS - 5, Design.RED);
|
||||||
|
ghosts[1] = new Ghost(COLS - 2, ROWS - 2, Design.ORANGE);
|
||||||
|
ghosts[2] = new Ghost(9, 7, Design.PINK);
|
||||||
|
ghosts[3] = new Ghost(COLS - 2, 4, Design.GREEN);
|
||||||
|
|
||||||
|
// Starte Timer mit 500ms Intervall
|
||||||
|
timer = new Timer(500, this);
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reagiere auf Timer-Events
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
// Bewege den Geist
|
||||||
|
for (Ghost ghost: ghosts) {
|
||||||
|
moveGhost(ghost);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prüfe auf Kollisionen
|
||||||
|
for (Ghost ghost : ghosts) {
|
||||||
|
checkCollisions(ghost);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aktualisiere die Darstellung
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override für das Zeichnen des Komponenten
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
// Zeichne das Labyrinth
|
||||||
|
drawLabyrinth(g);
|
||||||
|
// Zeichne Pacman
|
||||||
|
pacman.draw(g);
|
||||||
|
// Zeichne den Geist
|
||||||
|
for (Ghost ghost : ghosts) {
|
||||||
|
ghost.draw(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zeichne das Labyrinth
|
||||||
|
private void drawLabyrinth(Graphics g) {
|
||||||
|
for (int y = 0; y < ROWS; y++) {
|
||||||
|
for (int x = 0; x < COLS; x++) {
|
||||||
|
|
||||||
|
switch (labyrinth[y].charAt(x)) {
|
||||||
|
case '#': //Wall
|
||||||
|
g.setColor(Design.BLUE);
|
||||||
|
g.fillRect(
|
||||||
|
x * Design.CELL_SIZE,
|
||||||
|
y * Design.CELL_SIZE,
|
||||||
|
Design.CELL_SIZE,
|
||||||
|
Design.CELL_SIZE
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '.': //Point
|
||||||
|
g.setColor(Design.WHITE);
|
||||||
|
g.fillOval(
|
||||||
|
x * Design.CELL_SIZE + Design.CELL_SIZE / 2 - 5,
|
||||||
|
y * Design.CELL_SIZE + Design.CELL_SIZE / 2 - 5,
|
||||||
|
10,
|
||||||
|
10
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*': //Power pill
|
||||||
|
g.setColor(Design.WHITE);
|
||||||
|
g.fillOval(
|
||||||
|
x * Design.CELL_SIZE + Design.CELL_SIZE / 2 - 10,
|
||||||
|
y * Design.CELL_SIZE + Design.CELL_SIZE / 2 - 10,
|
||||||
|
20,
|
||||||
|
20
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-': //Ghost spawn barrier
|
||||||
|
g.setColor(Design.WHITE);
|
||||||
|
g.fillRect(
|
||||||
|
x * Design.CELL_SIZE,
|
||||||
|
y * Design.CELL_SIZE,
|
||||||
|
Design.CELL_SIZE,
|
||||||
|
10
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bewege Pacman, falls möglich
|
||||||
|
private void movePacman(int dx, int dy) {
|
||||||
|
int newX = pacman.x + dx;
|
||||||
|
int newY = pacman.y + dy;
|
||||||
|
|
||||||
|
//Check if pacman should be teleported. Same row teleportation only!
|
||||||
|
if (labyrinth[newY].charAt(newX) == '/') {
|
||||||
|
pacman.x = newX == 0 ? labyrinth[newY].length()-2 : 1;
|
||||||
|
pacman.y = newY;
|
||||||
|
}
|
||||||
|
// Überprüfe, ob das neue Feld kein Wand ist, bevor Pacman bewegt wird
|
||||||
|
else if (labyrinth[newY].charAt(newX) != '#' && labyrinth[newY].charAt(newX) != '-') {
|
||||||
|
pacman.x = newX;
|
||||||
|
pacman.y = newY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bewege den Geist in Richtung von Pacman
|
||||||
|
private void moveGhost(Ghost ghost) {
|
||||||
|
if (ghost.x < pacman.x && labyrinth[ghost.y].charAt(ghost.x + 1) != '#') {
|
||||||
|
ghost.x += 1;
|
||||||
|
} else if (ghost.x > pacman.x && labyrinth[ghost.y].charAt(ghost.x - 1) != '#') {
|
||||||
|
ghost.x -= 1;
|
||||||
|
} else if (ghost.y < pacman.y && labyrinth[ghost.y + 1].charAt(ghost.x) != '#') {
|
||||||
|
ghost.y += 1;
|
||||||
|
} else if (ghost.y > pacman.y && labyrinth[ghost.y - 1].charAt(ghost.x) != '#') {
|
||||||
|
ghost.y -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prüfe Kollisionen und Spielstatus
|
||||||
|
private void checkCollisions(Ghost ghost) {
|
||||||
|
// Kollision zwischen Pacman und Geist
|
||||||
|
if (pacman.x == ghost.x && pacman.y == ghost.y) {
|
||||||
|
if (ghost.isEatable) {
|
||||||
|
ghost.gotEaten();
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(this, "Game Over! The ghost caught Pacman.");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kollision Pacman mit einem Punkt
|
||||||
|
if (labyrinth[pacman.y].charAt(pacman.x) == '.') {
|
||||||
|
labyrinth[pacman.y] = labyrinth[pacman.y].substring(0, pacman.x) + " " + labyrinth[pacman.y].substring(pacman.x + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kollision Pacman mit einem Power Pill
|
||||||
|
if (labyrinth[pacman.y].charAt(pacman.x) == '*') {
|
||||||
|
labyrinth[pacman.y] = labyrinth[pacman.y].substring(0, pacman.x) + " " + labyrinth[pacman.y].substring(pacman.x + 1);
|
||||||
|
triggerPowerUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Überprüfen, ob alle Punkte gegessen sind
|
||||||
|
if (isAllCookiesEaten()) {
|
||||||
|
JOptionPane.showMessageDialog(this, "You Win! Pacman ate all the cookies.");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void triggerPowerUp() {
|
||||||
|
for (Ghost ghost: ghosts) {
|
||||||
|
ghost.makeGhostEatable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Überprüfe, ob alle Punkte gegessen wurden
|
||||||
|
private boolean isAllCookiesEaten() {
|
||||||
|
for (String row : labyrinth) {
|
||||||
|
if (row.contains(".")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erforderliche, aber nicht genutzte Methode von KeyListener
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {}
|
||||||
|
|
||||||
|
// Reagiere auf Tastendrücke
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
int key = e.getKeyCode();
|
||||||
|
// Steuere Pacman mit den Pfeiltasten
|
||||||
|
if (key == KeyEvent.VK_LEFT) {
|
||||||
|
movePacman(-1, 0);
|
||||||
|
} else if (key == KeyEvent.VK_RIGHT) {
|
||||||
|
movePacman(1, 0);
|
||||||
|
} else if (key == KeyEvent.VK_UP) {
|
||||||
|
movePacman(0, -1);
|
||||||
|
} else if (key == KeyEvent.VK_DOWN) {
|
||||||
|
movePacman(0, 1);
|
||||||
|
}
|
||||||
|
// Prüfe Kollisionen nach der Bewegung
|
||||||
|
for (Ghost ghost : ghosts) {
|
||||||
|
checkCollisions(ghost);
|
||||||
|
}
|
||||||
|
// Aktualisiere die Darstellung
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erforderliche, aber nicht genutzte Methode von KeyListener
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {}
|
||||||
|
|
||||||
|
// Hauptmethode zum Starten des Spiels
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JFrame frame = new JFrame("Pacman by Andres :v");
|
||||||
|
PacmanGame game = new PacmanGame();
|
||||||
|
frame.add(game);
|
||||||
|
frame.pack();
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.setLocationRelativeTo(null);
|
||||||
|
frame.setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue