import sys import random import pygame import numpy as np import rasterio from player import Player from enemy import Enemy from tapwater import TapWater from settings import PLAYER_SIZE, MAP_PATH, WIDTH, HEIGHT, MINIMAP_MARGIN DEBUG = False MAX_AMMO = 5 def play_video(win, video_path): """Play video with audio - extracts audio and plays with pygame mixer""" import cv2 import os import tempfile try: # Extract audio from video to temporary file audio_path = None try: from moviepy import VideoFileClip print("Extracting audio from video...") video = VideoFileClip(video_path) if video.audio: temp_audio = tempfile.NamedTemporaryFile(delete=False, suffix='.mp3') audio_path = temp_audio.name temp_audio.close() video.audio.write_audiofile(audio_path, logger=None) print(f"Audio extracted to: {audio_path}") # Play audio pygame.mixer.init() pygame.mixer.music.load(audio_path) pygame.mixer.music.play() print("Audio playback started") else: print("No audio track found in video") video.close() except Exception as e: print(f"Audio extraction warning: {e}") # Play video cap = cv2.VideoCapture(video_path) if not cap.isOpened(): print(f"Error: Could not open video file: {video_path}") return clock = pygame.time.Clock() running = True win_size = win.get_size() frame_count = 0 while running and cap.isOpened(): ret, frame = cap.read() if not ret: break frame_count += 1 frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Transpose for pygame (width, height) format frame = frame.swapaxes(0, 1) frame_surface = pygame.surfarray.make_surface(frame) frame_surface = pygame.transform.smoothscale(frame_surface, win_size) win.blit(frame_surface, (0, 0)) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.KEYDOWN or event.type == pygame.QUIT: running = False if audio_path: pygame.mixer.music.stop() clock.tick(30) cap.release() if audio_path: pygame.mixer.music.stop() print(f"Played {frame_count} video frames") # Clean up temp audio file if audio_path and os.path.exists(audio_path): try: os.unlink(audio_path) except: pass except Exception as e: print(f"Video playback error: {e}") print("Skipping video...") trinkbrunnen_positions = np.load('trinkbrunnen_pixel_positions.npy') # Nach dem Laden der Positionen: used_brunnen = [False] * len(trinkbrunnen_positions) pygame.init() # logo_img = pygame.image.load("images/logo.png") # pygame.display.set_icon(logo_img) WIN = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Wasser der Regierung") logo_img = pygame.image.load("images/Wasser_der_Regierung.PNG") pygame.display.set_icon(logo_img) def load_map(path): try: arr = rasterio.open(path).read(1) arr = np.nan_to_num(arr - 272.15, nan=0) arr = np.clip(arr, np.percentile(arr, 5), np.percentile(arr, 95)) arr = ((arr - arr.min()) / (arr.max() - arr.min()) * 255).astype(np.uint8) arr = np.stack([arr, arr, arr], -1) surf = pygame.surfarray.make_surface(arr) return surf, arr.shape[1], arr.shape[0] except Exception as e: print(f"Map load error: {e}") return None, WIDTH, HEIGHT map_surface, MAP_W, MAP_H = load_map(MAP_PATH) DIST_FACTOR = 2.0 # 2.0 = doppelte Entfernung, 1.0 = Standard # Karte vergrößern scaled_map = pygame.transform.smoothscale(map_surface, (int(MAP_W * DIST_FACTOR), int(MAP_H * DIST_FACTOR))) WIN.blit(scaled_map, (0, 0)) MINIMAP_WIDTH = 200 MINIMAP_HEIGHT = int(MAP_H / MAP_W * MINIMAP_WIDTH) def draw_minimap(win, map_surface, player, enemies, kranwasser): mini = pygame.transform.smoothscale(map_surface, (MINIMAP_WIDTH, MINIMAP_HEIGHT)) win.blit(mini, (WIDTH - MINIMAP_WIDTH - MINIMAP_MARGIN, MINIMAP_MARGIN)) def map2mini(x, y): mx = int(x / MAP_W * MINIMAP_WIDTH) my = int(y / MAP_H * MINIMAP_HEIGHT) return WIDTH - MINIMAP_WIDTH - MINIMAP_MARGIN + mx, MINIMAP_MARGIN + my pygame.draw.circle(win, (0, 255, 0), map2mini(player.x + PLAYER_SIZE // 2, player.y + PLAYER_SIZE // 2), 5) for enemy in enemies: color = (0, 128, 255) if enemy.is_human else (255, 0, 0) if enemy.controlled else (200, 200, 0) ex, ey = map2mini(enemy.x + PLAYER_SIZE // 4, enemy.y + PLAYER_SIZE // 4) pygame.draw.circle(win, color, (ex, ey), 5) for wasser in kranwasser: pygame.draw.circle(win, (0, 180, 255), map2mini(wasser.x, wasser.y), 3) def show_title_screen(win): title = pygame.image.load("images/Wasser_der_Regierung.PNG") title = pygame.transform.smoothscale(title, (WIDTH, HEIGHT)) win.blit(title,(0,0)) pygame.display.update() pygame.time.wait(3000) def show_win_screen(win): win.fill((40, 180, 80)) font = pygame.font.SysFont(None, 72) text = font.render("Gewonnen!", True, (255, 255, 255)) win.blit(text, (win.get_width() // 2 - text.get_width() // 2, win.get_height() // 2 - text.get_height() // 2)) pygame.display.update() pygame.time.wait(5000) def show_lose_screen(win): win.fill((180, 40, 40)) font = pygame.font.SysFont(None, 72) text = font.render("Verloren!", True, (255, 255, 255)) win.blit(text, (win.get_width() // 2 - text.get_width() // 2, win.get_height() // 2 - text.get_height() // 2)) pygame.display.update() pygame.time.wait(5000) def main(): from settings import PLAYER_IMG_PATH, ENEMY_IMG_PATH, HUMAN_IMG_PATH, PLAYER_SIZE, load_img player_img = load_img(PLAYER_IMG_PATH, (PLAYER_SIZE, PLAYER_SIZE)) enemy_img = load_img(ENEMY_IMG_PATH, (PLAYER_SIZE, PLAYER_SIZE)) human_img = load_img(HUMAN_IMG_PATH, (PLAYER_SIZE, PLAYER_SIZE)) player = Player(MAP_W // 2, MAP_H // 2, player_img) enemies = [ Enemy(random.randint(0, MAP_W - PLAYER_SIZE), random.randint(0, MAP_H - PLAYER_SIZE), enemy_img, human_img, i == 0) for i in range(20)] kranwasser = [] minimap_visible = True clock = pygame.time.Clock() play_video(WIN, "videos/test.mov") show_title_screen(WIN) running = True while running: clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: if player.ammo > 0: kranwasser.append(TapWater(player.x, player.y, player.dir)) player.ammo -= 1 else: print("Keine Munition!") if event.key == pygame.K_m: minimap_visible = not minimap_visible keys = pygame.key.get_pressed() player.move(keys, MAP_W, MAP_H) for enemy in enemies: enemy.move(keys, player, MAP_W, MAP_H) enemy.check_kill_player(player) for wasser in kranwasser[:]: for enemy in enemies: if enemy.rect.colliderect(wasser.rect): enemy.take_damage(20) kranwasser.remove(wasser) break kranwasser = [w for w in kranwasser if 0 <= w.x <= MAP_W and 0 <= w.y <= MAP_H] ox = max(0, min(player.x + PLAYER_SIZE // 2 - WIDTH // 2, MAP_W - WIDTH)) oy = max(0, min(player.y + PLAYER_SIZE // 2 - HEIGHT // 2, MAP_H - HEIGHT)) if scaled_map: WIN.blit(scaled_map, (0, 0), area=pygame.Rect(ox, oy, WIDTH, HEIGHT)) else: WIN.fill((255, 255, 255)) for px, py in trinkbrunnen_positions: pygame.draw.circle(WIN, (0, 0, 0), (px - ox, py - oy), 4) player.draw(WIN, ox, oy) for wasser in kranwasser: wasser.draw(WIN, ox, oy) for enemy in enemies: enemy.draw(WIN, ox, oy) if minimap_visible: draw_minimap(WIN, map_surface, player, enemies, kranwasser) player_rect = pygame.Rect(player.x, player.y, PLAYER_SIZE, PLAYER_SIZE) # Beim Auffüllen: for i, (px, py) in enumerate(trinkbrunnen_positions): brunnen_rect = pygame.Rect(px, py, 20, 20) if player_rect.colliderect(brunnen_rect) and not used_brunnen[i] and player.ammo < MAX_AMMO: player.ammo += 3 used_brunnen[i] = True # Brunnen blockieren font = pygame.font.SysFont(None, 32) ammo_text = font.render(f"Wasser: {player.ammo}", True, (0, 0, 255)) WIN.blit(ammo_text, (20, 20)) pygame.display.update() if not player.alive: show_lose_screen(WIN) running = False elif all(not e.alive or e.health <= 0 for e in enemies): show_win_screen(WIN) running = False pygame.quit() sys.exit() if __name__ == "__main__": main()