Dateien nach „Spiel Sitzung 04“ hochladen
This commit is contained in:
parent
1c0b24e4cf
commit
08cdd2be51
1 changed files with 414 additions and 0 deletions
414
Spiel Sitzung 04/Spiel.py
Normal file
414
Spiel Sitzung 04/Spiel.py
Normal file
|
|
@ -0,0 +1,414 @@
|
|||
|
||||
import sys
|
||||
from collections import deque
|
||||
|
||||
import pygame
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Maus im Käselabyrinth
|
||||
# 2D-Labyrinthspiel / Sammelspiel mit pygame
|
||||
# ------------------------------------------------------------
|
||||
# Installation, falls pygame noch fehlt:
|
||||
# pip install pygame
|
||||
#
|
||||
# Starten:
|
||||
# python maus_im_kaeselabyrinth.py
|
||||
# ------------------------------------------------------------
|
||||
|
||||
pygame.init()
|
||||
|
||||
# -----------------------------
|
||||
# Grundeinstellungen
|
||||
# -----------------------------
|
||||
TILE_SIZE = 32
|
||||
HUD_HEIGHT = 80
|
||||
FPS = 60
|
||||
CAT_MOVE_DELAY = 350 # Millisekunden zwischen Katzenbewegungen
|
||||
|
||||
# 0 = Weg, 1 = Wand
|
||||
maze = [
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
||||
[1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1],
|
||||
[1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1],
|
||||
[1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1],
|
||||
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
|
||||
[1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1],
|
||||
[1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1],
|
||||
[1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1],
|
||||
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
||||
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1],
|
||||
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1],
|
||||
[1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1],
|
||||
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
]
|
||||
|
||||
ROWS = len(maze)
|
||||
COLS = len(maze[0])
|
||||
WIDTH = COLS * TILE_SIZE
|
||||
HEIGHT = ROWS * TILE_SIZE + HUD_HEIGHT
|
||||
|
||||
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||
pygame.display.set_caption("Maus im Käselabyrinth")
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
font_big = pygame.font.SysFont("arial", 38, bold=True)
|
||||
font_medium = pygame.font.SysFont("arial", 24, bold=True)
|
||||
font_small = pygame.font.SysFont("arial", 18)
|
||||
|
||||
# -----------------------------
|
||||
# Farben
|
||||
# -----------------------------
|
||||
BACKGROUND = (247, 239, 210)
|
||||
PATH = (245, 215, 123)
|
||||
WALL = (95, 67, 36)
|
||||
WALL_DARK = (62, 43, 23)
|
||||
GRID_LINE = (220, 185, 85)
|
||||
MOUSE = (185, 185, 185)
|
||||
MOUSE_DARK = (120, 120, 120)
|
||||
CAT = (226, 124, 48)
|
||||
CAT_DARK = (140, 70, 25)
|
||||
CHEESE = (255, 214, 0)
|
||||
CHEESE_DARK = (199, 154, 0)
|
||||
BLACK = (20, 20, 20)
|
||||
WHITE = (255, 255, 255)
|
||||
RED = (190, 40, 40)
|
||||
GREEN = (40, 150, 70)
|
||||
|
||||
# -----------------------------
|
||||
# Spielvariablen
|
||||
# -----------------------------
|
||||
mouse_pos = [1, 1]
|
||||
cat_pos = [20, 13]
|
||||
cheeses = []
|
||||
score = 0
|
||||
game_state = "running" # running, won, game_over
|
||||
last_cat_move_time = 0
|
||||
|
||||
|
||||
def reset_game():
|
||||
"""Setzt alle Spielvariablen zurück."""
|
||||
global mouse_pos, cat_pos, cheeses, score, game_state, last_cat_move_time
|
||||
|
||||
mouse_pos = [1, 1]
|
||||
cat_pos = [20, 13]
|
||||
|
||||
# Liste mit genau 10 Käsestücken
|
||||
cheeses = [
|
||||
[3, 1],
|
||||
[8, 1],
|
||||
[15, 1],
|
||||
[20, 2],
|
||||
[5, 5],
|
||||
[13, 5],
|
||||
[1, 9],
|
||||
[9, 9],
|
||||
[15, 11],
|
||||
[18, 13],
|
||||
]
|
||||
|
||||
score = 0
|
||||
game_state = "running"
|
||||
last_cat_move_time = pygame.time.get_ticks()
|
||||
|
||||
|
||||
def is_wall(x, y):
|
||||
"""Prüft, ob sich an der Position eine Wand befindet."""
|
||||
if y < 0 or y >= ROWS or x < 0 or x >= COLS:
|
||||
return True
|
||||
return maze[y][x] == 1
|
||||
|
||||
|
||||
def move_mouse(dx, dy):
|
||||
"""Bewegt die Maus, falls keine Wand im Weg ist."""
|
||||
global mouse_pos
|
||||
|
||||
if game_state != "running":
|
||||
return
|
||||
|
||||
new_x = mouse_pos[0] + dx
|
||||
new_y = mouse_pos[1] + dy
|
||||
|
||||
# Bedingung: Die Maus darf nicht durch Wände laufen.
|
||||
if not is_wall(new_x, new_y):
|
||||
mouse_pos = [new_x, new_y]
|
||||
|
||||
collect_cheese()
|
||||
check_cat_collision()
|
||||
check_win()
|
||||
|
||||
|
||||
def collect_cheese():
|
||||
"""Prüft, ob die Maus Käse eingesammelt hat."""
|
||||
global score, cheeses
|
||||
|
||||
if mouse_pos in cheeses:
|
||||
cheeses.remove(mouse_pos.copy())
|
||||
score += 1
|
||||
|
||||
|
||||
def check_cat_collision():
|
||||
"""Prüft, ob Katze und Maus auf demselben Feld stehen."""
|
||||
global game_state
|
||||
|
||||
if mouse_pos == cat_pos:
|
||||
game_state = "game_over"
|
||||
|
||||
|
||||
def check_win():
|
||||
"""Prüft, ob alle 10 Käsestücke gesammelt wurden."""
|
||||
global game_state
|
||||
|
||||
if score == 10 and game_state == "running":
|
||||
game_state = "won"
|
||||
|
||||
|
||||
def get_neighbors(position):
|
||||
"""Gibt alle begehbaren Nachbarfelder zurück."""
|
||||
x, y = position
|
||||
directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
|
||||
neighbors = []
|
||||
|
||||
for dx, dy in directions:
|
||||
next_x = x + dx
|
||||
next_y = y + dy
|
||||
if not is_wall(next_x, next_y):
|
||||
neighbors.append([next_x, next_y])
|
||||
|
||||
return neighbors
|
||||
|
||||
|
||||
def find_shortest_path(start, goal):
|
||||
"""
|
||||
Sucht mit einer Breitensuche einen Weg von der Katze zur Maus.
|
||||
Dadurch bewegt sich die Katze sinnvoll durch das Labyrinth.
|
||||
"""
|
||||
queue = deque()
|
||||
queue.append((start, []))
|
||||
visited = {tuple(start)}
|
||||
|
||||
while queue:
|
||||
current, path = queue.popleft()
|
||||
|
||||
if current == goal:
|
||||
return path
|
||||
|
||||
for neighbor in get_neighbors(current):
|
||||
key = tuple(neighbor)
|
||||
if key not in visited:
|
||||
visited.add(key)
|
||||
queue.append((neighbor, path + [neighbor]))
|
||||
|
||||
return []
|
||||
|
||||
|
||||
def move_cat():
|
||||
"""Bewegt die Katze einen Schritt in Richtung Maus."""
|
||||
global cat_pos
|
||||
|
||||
if game_state != "running":
|
||||
return
|
||||
|
||||
path = find_shortest_path(cat_pos, mouse_pos)
|
||||
|
||||
if path:
|
||||
cat_pos = path[0]
|
||||
|
||||
check_cat_collision()
|
||||
|
||||
|
||||
def draw_hud():
|
||||
"""Zeichnet Titel, Punkte und Hinweise."""
|
||||
pygame.draw.rect(screen, BACKGROUND, (0, 0, WIDTH, HUD_HEIGHT))
|
||||
|
||||
title = font_medium.render("Maus im Käselabyrinth", True, BLACK)
|
||||
score_text = font_medium.render(f"Punkte: {score} / 10", True, BLACK)
|
||||
|
||||
if game_state == "running":
|
||||
status = "Status: Spiel läuft"
|
||||
status_color = BLACK
|
||||
elif game_state == "won":
|
||||
status = "Status: Gewonnen!"
|
||||
status_color = GREEN
|
||||
else:
|
||||
status = "Status: Game Over!"
|
||||
status_color = RED
|
||||
|
||||
status_text = font_medium.render(status, True, status_color)
|
||||
help_text = font_small.render("Steuerung: Pfeiltasten oder W, A, S, D | R = Neustart | ESC = Beenden", True, BLACK)
|
||||
|
||||
screen.blit(title, (20, 10))
|
||||
screen.blit(score_text, (20, 42))
|
||||
screen.blit(status_text, (250, 42))
|
||||
screen.blit(help_text, (20, 64))
|
||||
|
||||
|
||||
def draw_maze():
|
||||
"""Zeichnet Labyrinth mit Wegen und Wänden."""
|
||||
for y in range(ROWS):
|
||||
for x in range(COLS):
|
||||
rect = pygame.Rect(x * TILE_SIZE, HUD_HEIGHT + y * TILE_SIZE, TILE_SIZE, TILE_SIZE)
|
||||
|
||||
if maze[y][x] == 1:
|
||||
pygame.draw.rect(screen, WALL, rect)
|
||||
pygame.draw.rect(screen, WALL_DARK, rect, 2)
|
||||
else:
|
||||
pygame.draw.rect(screen, PATH, rect)
|
||||
pygame.draw.rect(screen, GRID_LINE, rect, 1)
|
||||
|
||||
|
||||
def draw_cheese(x, y):
|
||||
"""Zeichnet ein Käsestück."""
|
||||
center_x = x * TILE_SIZE + TILE_SIZE // 2
|
||||
center_y = HUD_HEIGHT + y * TILE_SIZE + TILE_SIZE // 2
|
||||
|
||||
points = [
|
||||
(center_x - 11, center_y + 10),
|
||||
(center_x + 12, center_y),
|
||||
(center_x - 11, center_y - 10),
|
||||
]
|
||||
pygame.draw.polygon(screen, CHEESE, points)
|
||||
pygame.draw.polygon(screen, CHEESE_DARK, points, 2)
|
||||
|
||||
pygame.draw.circle(screen, CHEESE_DARK, (center_x - 3, center_y), 2)
|
||||
pygame.draw.circle(screen, CHEESE_DARK, (center_x + 4, center_y - 3), 2)
|
||||
pygame.draw.circle(screen, CHEESE_DARK, (center_x + 4, center_y + 4), 2)
|
||||
|
||||
|
||||
def draw_mouse():
|
||||
"""Zeichnet die Maus."""
|
||||
x, y = mouse_pos
|
||||
center_x = x * TILE_SIZE + TILE_SIZE // 2
|
||||
center_y = HUD_HEIGHT + y * TILE_SIZE + TILE_SIZE // 2
|
||||
|
||||
# Ohren
|
||||
pygame.draw.circle(screen, MOUSE_DARK, (center_x - 8, center_y - 9), 5)
|
||||
pygame.draw.circle(screen, MOUSE_DARK, (center_x + 8, center_y - 9), 5)
|
||||
|
||||
# Körper
|
||||
pygame.draw.circle(screen, MOUSE, (center_x, center_y), 11)
|
||||
pygame.draw.circle(screen, BLACK, (center_x, center_y + 2), 2)
|
||||
|
||||
# Schwanz
|
||||
pygame.draw.line(screen, MOUSE_DARK, (center_x - 10, center_y + 4), (center_x - 17, center_y + 10), 2)
|
||||
|
||||
|
||||
def draw_cat():
|
||||
"""Zeichnet die Katze."""
|
||||
x, y = cat_pos
|
||||
center_x = x * TILE_SIZE + TILE_SIZE // 2
|
||||
center_y = HUD_HEIGHT + y * TILE_SIZE + TILE_SIZE // 2
|
||||
|
||||
# Kopf
|
||||
pygame.draw.circle(screen, CAT, (center_x, center_y), 12)
|
||||
|
||||
# Ohren
|
||||
left_ear = [(center_x - 10, center_y - 7), (center_x - 4, center_y - 18), (center_x, center_y - 7)]
|
||||
right_ear = [(center_x + 10, center_y - 7), (center_x + 4, center_y - 18), (center_x, center_y - 7)]
|
||||
pygame.draw.polygon(screen, CAT, left_ear)
|
||||
pygame.draw.polygon(screen, CAT, right_ear)
|
||||
pygame.draw.polygon(screen, CAT_DARK, left_ear, 2)
|
||||
pygame.draw.polygon(screen, CAT_DARK, right_ear, 2)
|
||||
|
||||
# Augen
|
||||
pygame.draw.circle(screen, BLACK, (center_x - 4, center_y - 2), 2)
|
||||
pygame.draw.circle(screen, BLACK, (center_x + 4, center_y - 2), 2)
|
||||
|
||||
# Nase
|
||||
pygame.draw.circle(screen, CAT_DARK, (center_x, center_y + 4), 2)
|
||||
|
||||
|
||||
def draw_end_message():
|
||||
"""Zeichnet Gewinn- oder Game-Over-Meldung."""
|
||||
if game_state == "running":
|
||||
return
|
||||
|
||||
box_width = 500
|
||||
box_height = 160
|
||||
box_x = WIDTH // 2 - box_width // 2
|
||||
box_y = HEIGHT // 2 - box_height // 2
|
||||
|
||||
pygame.draw.rect(screen, (0, 0, 0), (box_x, box_y, box_width, box_height), border_radius=16)
|
||||
pygame.draw.rect(screen, WHITE, (box_x + 5, box_y + 5, box_width - 10, box_height - 10), border_radius=14)
|
||||
|
||||
if game_state == "won":
|
||||
title = "GEWONNEN!"
|
||||
subtitle = "Du hast alle 10 Käsestücke gesammelt."
|
||||
color = GREEN
|
||||
else:
|
||||
title = "GAME OVER!"
|
||||
subtitle = "Die Katze hat die Maus gefangen."
|
||||
color = RED
|
||||
|
||||
title_text = font_big.render(title, True, color)
|
||||
subtitle_text = font_medium.render(subtitle, True, BLACK)
|
||||
restart_text = font_small.render("Drücke R, um neu zu starten.", True, BLACK)
|
||||
|
||||
screen.blit(title_text, title_text.get_rect(center=(WIDTH // 2, box_y + 48)))
|
||||
screen.blit(subtitle_text, subtitle_text.get_rect(center=(WIDTH // 2, box_y + 92)))
|
||||
screen.blit(restart_text, restart_text.get_rect(center=(WIDTH // 2, box_y + 128)))
|
||||
|
||||
|
||||
def draw_game():
|
||||
"""Zeichnet das gesamte Spiel neu."""
|
||||
screen.fill(BACKGROUND)
|
||||
draw_hud()
|
||||
draw_maze()
|
||||
|
||||
for cheese in cheeses:
|
||||
draw_cheese(cheese[0], cheese[1])
|
||||
|
||||
draw_mouse()
|
||||
draw_cat()
|
||||
draw_end_message()
|
||||
|
||||
pygame.display.flip()
|
||||
|
||||
|
||||
def handle_keydown(key):
|
||||
"""Reagiert auf Tastatureingaben."""
|
||||
if key in (pygame.K_ESCAPE,):
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
|
||||
if key == pygame.K_r:
|
||||
reset_game()
|
||||
return
|
||||
|
||||
if key in (pygame.K_UP, pygame.K_w):
|
||||
move_mouse(0, -1)
|
||||
elif key in (pygame.K_DOWN, pygame.K_s):
|
||||
move_mouse(0, 1)
|
||||
elif key in (pygame.K_LEFT, pygame.K_a):
|
||||
move_mouse(-1, 0)
|
||||
elif key in (pygame.K_RIGHT, pygame.K_d):
|
||||
move_mouse(1, 0)
|
||||
|
||||
|
||||
def main():
|
||||
"""Game Loop: Eingaben lesen, Spiel aktualisieren, neu zeichnen."""
|
||||
global last_cat_move_time
|
||||
|
||||
reset_game()
|
||||
|
||||
while True:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
|
||||
if event.type == pygame.KEYDOWN:
|
||||
handle_keydown(event.key)
|
||||
|
||||
current_time = pygame.time.get_ticks()
|
||||
if current_time - last_cat_move_time >= CAT_MOVE_DELAY:
|
||||
move_cat()
|
||||
last_cat_move_time = current_time
|
||||
|
||||
draw_game()
|
||||
clock.tick(FPS)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in a new issue