Letzte Übung :)

main
Andres Alberto Cruz Aguirre 2024-12-29 21:12:00 +01:00
parent dc7510f715
commit 666f0ac6aa
4 changed files with 397 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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