Einführung
In diesem Projekt werden wir ein Labyrinthspiel mit der Pygame-Bibliothek in Python erstellen. Beim Spiel muss ein Spieler durch ein Labyrinth navigieren, um Lebensmittel zu sammeln, während er die Mauern vermeidet. Wir werden den Entwicklungsprozess in mehrere Schritte unterteilen, um ihn einfacher zu verstehen und zu folgen.
👀 Vorschau

🎯 Aufgaben
In diesem Projekt lernst du:
- Wie man die Spielumgebung mit Pygame einrichtet
- Wie man das Labyrinth mit Zellen und Mauern erstellt
- Wie man Lebensmittel für den Spieler hinzufügt, die er sammeln kann
- Wie man die Spielerbewegung und die Kollisionserkennung implementiert
- Wie man die Spiellogik behandelt, einschließlich der Punktzahl und der Spielende-Bedingungen
- Wie man den Spielerrekord verfolgt
- Wie man Spielstatistiken wie Zeit, Punktzahl und Rekord auf dem Bildschirm anzeigt
🏆 Errungenschaften
Nach Abschluss dieses Projekts wirst du in der Lage sein:
- Die Pygame-Bibliothek für die Spielentwicklung zu verwenden
- Konzepte der objektorientierten Programmierung anwenden, um Spielelemente zu erstellen
- Algorithmisches Denken und Problemlösefähigkeiten für die Labyrinthgenerierung demonstrieren
- Ereignisverarbeitung und Spielerinput behandeln
- Kollisionserkennung und Bewegungmechaniken in einer Spielumgebung implementieren
- Dateiverarbeitung zur Speicherung und Abrufung von Spielrekorden verwalten
- Spielstatistiken und Informationen auf dem Bildschirm anzeigen
Einrichten der Umgebung
Zunächst erstellen wir die Projekt-Dateien für das Labyrinthspiel.
cd ~/project
touch maze.py
sudo pip install pygame
In diesem Schritt richten wir die Pygame-Umgebung ein und definieren Konstanten.
import pygame
from random import choice, randrange
## Konstanten für die Bildschirmdimensionen und die Kachelgröße
RES = WIDTH, HEIGHT = 1202, 902
TILE = 100
cols, rows = WIDTH // TILE, HEIGHT // TILE
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir importieren die erforderlichen Bibliotheken (Pygame und random).
- Wir definieren Konstanten für die Bildschirmdimensionen und die Kachelgröße.
- Pygame wird initialisiert, und das Spielfenster wird eingerichtet.
- Wir laden Hintergrundbilder für das Spiel.
Erstellen der Cell-Klasse
In diesem Schritt definieren wir die Cell-Klasse, um Labyrinthzellen zu repräsentieren.
## Definiere eine Klasse, um Zellen im Labyrinth zu repräsentieren
class Cell:
def __init__(self, x, y):
self.x, self.y = x, y
## Mauern repräsentieren die Grenzen der Zelle
self.walls = {"top": True, "right": True, "bottom": True, "left": True}
self.visited = False
self.thickness = 4
## Zeichne die Mauern der Zelle
def draw(self, sc):
x, y = self.x * TILE, self.y * TILE
if self.walls["top"]:
pygame.draw.line(
sc, pygame.Color("darkorange"), (x, y), (x + TILE, y), self.thickness
)
if self.walls["right"]:
pygame.draw.line(
sc,
pygame.Color("darkorange"),
(x + TILE, y),
(x + TILE, y + TILE),
self.thickness,
)
if self.walls["bottom"]:
pygame.draw.line(
sc,
pygame.Color("darkorange"),
(x + TILE, y + TILE),
(x, y + TILE),
self.thickness,
)
if self.walls["left"]:
pygame.draw.line(
sc, pygame.Color("darkorange"), (x, y + TILE), (x, y), self.thickness
)
## Hole die Rechtecke, die jede Mauer der Zelle repräsentieren
def get_rects(self):
rects = []
x, y = self.x * TILE, self.y * TILE
if self.walls["top"]:
rects.append(pygame.Rect((x, y), (TILE, self.thickness)))
if self.walls["right"]:
rects.append(pygame.Rect((x + TILE, y), (self.thickness, TILE)))
if self.walls["bottom"]:
rects.append(pygame.Rect((x, y + TILE), (TILE, self.thickness)))
if self.walls["left"]:
rects.append(pygame.Rect((x, y), (self.thickness, TILE)))
return rects
## Überprüfe, ob eine Nachbarzelle existiert
def check_cell(self, x, y):
find_index = lambda x, y: x + y * cols
if x < 0 or x > cols - 1 or y < 0 or y > rows - 1:
return False
return self.grid_cells[find_index(x, y)]
## Hole nicht besuchte Nachbarzellen
def check_neighbors(self, grid_cells):
self.grid_cells = grid_cells
neighbors = []
top = self.check_cell(self.x, self.y - 1)
right = self.check_cell(self.x + 1, self.y)
bottom = self.check_cell(self.x, self.y + 1)
left = self.check_cell(self.x - 1, self.y)
if top and not top.visited:
neighbors.append(top)
if right and not right.visited:
neighbors.append(right)
if bottom and not bottom.visited:
neighbors.append(bottom)
if left and not left.visited:
neighbors.append(left)
return choice(neighbors) if neighbors else False
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir definieren die
Cell-Klasse mit ihren Eigenschaften und Methoden zum Zeichnen von Mauern und zum Überprüfen von Nachbarn.
Wände entfernen und das Labyrinth generieren
In diesem Schritt erstellen wir Funktionen, um Mauern zu entfernen und das Labyrinth zu generieren.
## Funktion, um Mauern zwischen zwei angrenzenden Zellen zu entfernen
def remove_walls(current, next):
dx = current.x - next.x
if dx == 1:
current.walls["left"] = False
next.walls["right"] = False
elif dx == -1:
current.walls["right"] = False
next.walls["left"] = False
dy = current.y - next.y
if dy == 1:
current.walls["top"] = False
next.walls["bottom"] = False
elif dy == -1:
current.walls["bottom"] = False
next.walls["top"] = False
## Funktion, um das Labyrinth zu generieren
def generate_maze():
grid_cells = [Cell(col, row) for row in range(rows) for col in range(cols)]
current_cell = grid_cells[0]
array = []
break_count = 1
while break_count!= len(grid_cells):
current_cell.visited = True
next_cell = current_cell.check_neighbors(grid_cells)
if next_cell:
next_cell.visited = True
break_count += 1
array.append(current_cell)
remove_walls(current_cell, next_cell)
current_cell = next_cell
elif array:
current_cell = array.pop()
return grid_cells
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir definieren die
remove_walls-Funktion, um Mauern zwischen angrenzenden Zellen zu entfernen. - Wir erstellen die
generate_maze-Funktion, um das Labyrinth mit einem Tiefensuche-Algorithmus zu generieren.
Lebensmittel zum Spiel hinzufügen
In diesem Schritt erstellen wir eine Food-Klasse, um Lebensmittel zu unserem Spiel hinzuzufügen.
## Klasse, um Lebensmittel im Spiel zu repräsentieren
class Food:
def __init__(self):
## Lade das Lebensmittel-Bild
self.img = pygame.image.load("img/food.png").convert_alpha()
self.img = pygame.transform.scale(self.img, (TILE - 10, TILE - 10))
self.rect = self.img.get_rect()
self.set_pos()
## Setze die Position des Lebensmittels zufällig
def set_pos(self):
self.rect.topleft = randrange(cols) * TILE + 5, randrange(rows) * TILE + 5
## Zeichne das Lebensmittel auf dem Bildschirm
def draw(self):
game_surface.blit(self.img, self.rect)
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir definieren die
Food-Klasse mit Methoden zum Setzen der Position und Zeichnen von Lebensmitteln.
Spielerbewegung und Kollisionserkennung
In diesem Schritt richten wir die Spielersteuerung, -bewegung und -kollisionserkennung ein.
## Überprüfe, ob der Spieler mit Mauern kollidiert
def is_collide(x, y):
tmp_rect = player_rect.move(x, y)
if tmp_rect.collidelist(walls_collide_list) == -1:
return False
return True
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir definieren die
is_collide-Funktion, um zu überprüfen, ob der Spieler mit Mauern kollidiert.
Spielablauf und Punktesystem
In diesem Schritt implementieren wir die Spielablauflogik, einschließlich Essen von Lebensmitteln und Punktestand.
## Überprüfe, ob der Spieler Lebensmittel gegessen hat
def eat_food():
for food in food_list:
if player_rect.collidepoint(food.rect.center):
food.set_pos()
return True
return False
## Überprüfe, ob das Spiel vorbei ist (Zeit abgelaufen)
def is_game_over():
global time, score, record, FPS
if time < 0:
pygame.time.wait(700)
player_rect.center = TILE // 2, TILE // 2
[food.set_pos() for food in food_list]
set_record(record, score)
record = get_record()
time, score, FPS = 60, 0, 60
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir definieren die
eat_food-Funktion, um zu überprüfen, ob der Spieler Lebensmittel gegessen hat. - Wir erstellen die
is_game_over-Funktion, um zu überprüfen, ob das Spiel vorbei ist, wenn die Zeit abgelaufen ist.
Datensätze verarbeiten
In diesem Schritt implementieren wir die Aufzeichnung von Ergebnissen für das Spiel.
## Funktion, um den aktuellen Rekord aus einer Datei zu erhalten
def get_record():
try:
with open("record") as f:
return f.readline()
except FileNotFoundError:
with open("record", "w") as f:
f.write("0")
return "0"
## Funktion, um den Rekord in einer Datei festzulegen und zu aktualisieren
def set_record(record, score):
rec = max(int(record), score)
with open("record", "w") as f:
f.write(str(rec))
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir definieren Funktionen, um den aktuellen Rekord aus einer Datei abzurufen und zu aktualisieren.
Spielinitialisierung
In diesem Schritt führen wir die Spielinitialisierungstasks aus.
## Initialisiere Pygame und stelle das Spielfenster ein
FPS = 60
pygame.init()
game_surface = pygame.Surface(RES)
surface = pygame.display.set_mode((WIDTH + 300, HEIGHT))
clock = pygame.time.Clock()
## Lade Hintergrundbilder
bg_game = pygame.image.load("img/bg_1.jpg").convert()
bg = pygame.image.load("img/bg_main.jpg").convert()
## Generiere das Labyrinth
maze = generate_maze()
## Spieler-Einstellungen
player_speed = 5
player_img = pygame.image.load("img/0.png").convert_alpha()
player_img = pygame.transform.scale(
player_img, (TILE - 2 * maze[0].thickness, TILE - 2 * maze[0].thickness)
)
player_rect = player_img.get_rect()
player_rect.center = TILE // 2, TILE // 2
directions = {
"a": (-player_speed, 0),
"d": (player_speed, 0),
"w": (0, -player_speed),
"s": (0, player_speed),
}
keys = {"a": pygame.K_LEFT, "d": pygame.K_RIGHT, "w": pygame.K_UP, "s": pygame.K_DOWN}
direction = (0, 0)
## Lebensmittel-Einstellungen
food_list = [Food() for i in range(3)]
## Erstelle eine Liste von Rechtecken, die die Mauern für die Kollisionserkennung repräsentieren
walls_collide_list = sum([cell.get_rects() for cell in maze], [])
## Timer, Punktestand und Rekord
pygame.time.set_timer(pygame.USEREVENT, 1000)
time = 60
score = 0
record = get_record()
## Schriftarten
font = pygame.font.SysFont("Impact", 150)
text_font = pygame.font.SysFont("Impact", 80)
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir führen verschiedene Initialisierungstasks aus, einschließlich des Einrichtens von Pygame, des Ladens von Bildern, der Generierung des Labyrinths und der Initialisierung von Variablen, die mit Spieler und Lebensmitteln zusammenhängen.
Hauptspielschleife
In diesem Schritt richten wir die Hauptspielschleife ein und zeichnen die Spiel-Elemente.
## Hauptspielschleife
while True:
## Zeichne Hintergrundbilder
surface.blit(bg, (WIDTH, 0))
surface.blit(game_surface, (0, 0))
game_surface.blit(bg_game, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == pygame.USEREVENT:
time -= 1
## Verarbeite Spielersteuerungen und Bewegung
pressed_key = pygame.key.get_pressed()
for key, key_value in keys.items():
if pressed_key[key_value] and not is_collide(*directions[key]):
direction = directions[key]
break
if not is_collide(*direction):
player_rect.move_ip(direction)
## Zeichne das Labyrinth
[cell.draw(game_surface) for cell in maze]
## Spielablauf: Überprüfe, ob der Spieler Lebensmittel gegessen hat und ob das Spiel vorbei ist
if eat_food():
FPS += 10
score += 1
is_game_over()
## Zeichne den Spieler
game_surface.blit(player_img, player_rect)
## Zeichne Lebensmittelgegenstände
[food.draw() for food in food_list]
## Der Rest Ihres Codes wird hier stehen...
In diesem Schritt:
- Wir richten die Hauptspielschleife ein, die Ereignisse, Spielerbewegung und Spielrendern behandelt.
Anzeige von Spielstatistiken
In diesem Schritt werden wir Spielstatistiken auf dem Bildschirm anzeigen.
## Zeichne Spielstatistiken
surface.blit(
text_font.render("ZEIT", True, pygame.Color("cyan"), True), (WIDTH + 70, 30)
)
surface.blit(font.render(f"{time}", True, pygame.Color("cyan")), (WIDTH + 70, 130))
surface.blit(
text_font.render("Punkte:", True, pygame.Color("forestgreen"), True),
(WIDTH + 50, 350),
)
surface.blit(
font.render(f"{score}", True, pygame.Color("forestgreen")), (WIDTH + 70, 430)
)
surface.blit(
text_font.render("Rekord:", True, pygame.Color("magenta"), True),
(WIDTH + 30, 620),
)
surface.blit(
font.render(f"{record}", True, pygame.Color("magenta")), (WIDTH + 70, 700)
)
pygame.display.flip()
clock.tick(FPS)
In diesem Schritt:
- Wir verwenden Schriftarten, um spielbezogene Informationen wie Zeit, Punkte und den Rekord anzuzeigen.
- Wir verwenden die
blit()-Methode, um den Text auf dem Bildschirm zu zeichnen. - Wir verwenden die
flip()-Methode, um die Anzeige zu aktualisieren.
Spiel ausführen
Jetzt, nachdem wir alle Schritte abgeschlossen haben, können wir das Labyrinthspiel mit dem folgenden Befehl starten:
cd ~/project
python maze.py

Zusammenfassung
In diesem Projekt haben wir den Prozess des Erstellens eines Labyrinthspiels mit Pygame in zehn klare und handhabbare Schritte unterteilt. Du wirst lernen, wie du die Spielumgebung einrichtest, Labyrinthzellen erstellst, das Labyrinth generierst, die Spielerbewegung und die Kollisionserkennung behandelst, das Spielgeschehen und die Punktzahl implementierst, die Aufzeichnungen verwaltest und vieles mehr. Indem du diesen Schritten folgst, wirst du in der Lage sein, ein voll funktionsfähiges Labyrinthspiel in Python zu erstellen.



