cdec/README_TIPS.md
2025-10-12 11:25:00 +02:00

9.6 KiB

Tipps & Hinweise

Titelbild und Logo einfügen

  • Ein Logo macht das Spiel persönlicher! Die Funktion zum Laden eines Logos ist im Code vorbereitet, aber aktuell deaktiviert.

  • Die Kids können später ein eigenes Logo als images/logo.png erstellen und die folgende Zeile in water-game.py aktivieren:

    # logo_img = pygame.image.load("images/logo.png")
    # pygame.display.set_icon(logo_img)
    
  • Tipp: Das Logo sollte quadratisch und als PNG gespeichert sein.

  • So kann jeder sein eigenes Spiel-Icon gestalten!

Titelbildschirm, Gewinn- und Verlustbildschirm

  • Implementiere einen Titelbildschirm und zeige bei Spielende einen Gewinn- oder Verlustbildschirm (siehe Codebeispiel unten).

Beispiel für Titelbildschirm und Gewinn/Verlust:

# Titelbildschirm anzeigen
show_title_screen(WIN)
# ...
if win_condition:
    show_win_screen(WIN)
elif lose_condition:
    show_lose_screen(WIN)

So kannst du Gewinn- und Verlustbildschirme umsetzen:

  1. Schreibe eine Funktion, die den Bildschirm einfärbt und einen Text anzeigt:
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(2500)

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(2500)
  1. Rufe die jeweilige Funktion auf, wenn die Gewinn- oder Verlustbedingung erfüllt ist:
if win_condition:
    show_win_screen(WIN)
elif lose_condition:
    show_lose_screen(WIN)
  • Die Bedingungen kannst du selbst festlegen, z.B. alle Gegner besiegt = Gewinn, Spieler tot = Verlust.
  • Nach dem Bildschirm kannst du das Spiel beenden oder neu starten.

Trinkbrunnen-Pixelpositionen ins Spiel laden und anzeigen

  • Die Datei trinkbrunnen_pixel_positions.npy enthält alle Trinkbrunnen-Positionen als Pixelkoordinaten.
  • So lädst du die Positionen und zeichnest die Trinkbrunnen im Spiel:

Schritt 1: Importiere numpy und lade die Datei

import numpy as np
trinkbrunnen_positions = np.load('trinkbrunnen_pixel_positions.npy')

Schritt 2: Zeichne die Trinkbrunnen in der Spielschleife

for px, py in trinkbrunnen_positions:
    pygame.draw.circle(WIN, (0, 180, 255), (px - ox, py - oy), 10)
  • ox und oy sind die Offsets für das Kamerascrolling (falls verwendet).
  • Die Farbe (0, 180, 255) ist ein helles Blau, der Radius 10 kann angepasst werden.

Schritt 3: Interaktion mit Trinkbrunnen

  • Um z.B. Munition aufzufüllen, prüfe ob der Spieler einen Trinkbrunnen berührt:
player_rect = pygame.Rect(player.x, player.y, PLAYER_SIZE, PLAYER_SIZE)
for px, py in trinkbrunnen_positions:
    brunnen_rect = pygame.Rect(px, py, 20, 20)  # Größe anpassen
    if player_rect.colliderect(brunnen_rect):
        player.ammo = MAX_AMMO
  • So werden die Trinkbrunnen sichtbar und interaktiv im Spiel!

Die Karte größer machen (Abstandsfaktor)

  • Wenn du möchtest, dass die Karte größer wirkt und die Abstände zwischen den Trinkbrunnen (und anderen Objekten) wachsen, kannst du einen "Abstandsfaktor" einführen.
  • Damit werden alle Positionen und die Kartengröße mit einem Faktor multipliziert, sodass die Karte gestreckt wird und die Wege länger werden.

So geht's:

Wo und wie den Abstandsfaktor einbauen?

  1. Definiere den Abstandsfaktor ganz oben in deiner Hauptdatei (z.B. water-game.py):
DIST_FACTOR = 2.0  # Beispielwert, kann angepasst werden
  1. Wende den Faktor direkt nach dem Laden der Daten an:
  • Nachdem du die Trinkbrunnen-Positionen und ggf. die Spieler-/Gegner-Positionen geladen hast, multipliziere sie mit dem Abstandsfaktor:
# Nach dem Laden der Trinkbrunnen-Positionen
trinkbrunnen_positions = np.load('trinkbrunnen_pixel_positions.npy')
trinkbrunnen_positions = [(int(px * DIST_FACTOR), int(py * DIST_FACTOR)) for px, py in trinkbrunnen_positions]

# Spieler und Gegner ebenfalls anpassen (direkt nach deren Initialisierung):
player.x *= DIST_FACTOR
player.y *= DIST_FACTOR
for enemy in enemies:
    enemy.x *= DIST_FACTOR
    enemy.y *= DIST_FACTOR
  1. Beim Rendern der Karte:
  • Skaliere die Karte beim Anzeigen:
scaled_map = pygame.transform.smoothscale(map_surface, (int(MAP_W * DIST_FACTOR), int(MAP_H * DIST_FACTOR)))
WIN.blit(scaled_map, (0, 0))

Tipp:

  • Der Abstandsfaktor sollte immer am Anfang und nur einmal auf die Positionen angewendet werden, damit alle Objekte synchron gestreckt werden.
  • Passe ggf. auch die Spielfeldgröße (WIDTH, HEIGHT) an, wenn die Karte sehr groß wird.

Schnelles Skalieren der Karte nach dem Laden

  • Statt alle Positionen und Objekte zu multiplizieren, kannst du die Karte direkt nach dem Laden einmalig skalieren und die Originalkoordinaten beibehalten.
  • Das ist viel schneller und spart Rechenzeit!

So geht's:

  1. Karte nach dem Laden skalieren:
DIST_FACTOR = 2.0  # Beispielwert

# Nach dem Laden der Karte (z.B. map_surface):
scaled_map = pygame.transform.smoothscale(map_surface, (int(MAP_W * DIST_FACTOR), int(MAP_H * DIST_FACTOR)))
  1. Beim Rendern die Karte und alle Objekte mit dem Faktor verschieben:
WIN.blit(scaled_map, (0, 0))
for px, py in trinkbrunnen_positions:
    pygame.draw.circle(WIN, (0, 180, 255), (int(px * DIST_FACTOR), int(py * DIST_FACTOR)), 10)
# Spieler, Gegner usw. ebenfalls mit DIST_FACTOR multiplizieren, aber nur beim Zeichnen!
  • Die Positionsdaten bleiben im Speicher unverändert, nur die Darstellung wird gestreckt.
  • Das ist besonders bei großen Karten und vielen Objekten viel performanter.
  • Du kannst den Abstandsfaktor jederzeit ändern, ohne die Originaldaten zu verlieren.

.exe erstellen (Windows)

Kurzanleitung auf Deutsch:

  1. Installiere PyInstaller:

    pip install pyinstaller
    
  2. Konvertiere dein Logo zu einer .ico-Datei (z.B. mit favicon.io).

  3. Erstelle die .exe:

    pyinstaller --onefile --windowed --icon=images/logo.ico water-game.py
    
  4. Die ausführbare Datei findest du im dist-Ordner.

Mac: App als ausführbare Datei erstellen

Kurzanleitung auf Deutsch:

  1. Installiere PyInstaller:

    pip install pyinstaller
    
  2. Erstelle die Mac-App:

    pyinstaller --onefile --windowed --icon=images/logo.png water-game.py
    
    • Das Icon kann als PNG verwendet werden.
    • Die App wird im dist-Ordner als ausführbare Datei erscheinen.
  3. (Optional) Um eine echte Mac-App zu erzeugen, nutze das Flag --name und --osx-bundle-identifier:

    pyinstaller --onefile --windowed --icon=images/logo.png --name=WasserGame --osx-bundle-identifier=com.deinname.wassergame water-game.py
    

Hinweis:

  • Die App kann per Doppelklick gestartet werden.
  • Für die Verteilung an andere Macs kann eine Code-Signierung und Notarisierung nötig sein (siehe Apple Doku).

Tipp: Intro-Video vor Spielstart abspielen

  • Du kannst ein Video (z.B. MP4) als Intro vor dem eigentlichen Spiel abspielen.
  • Nutze dazu z.B. die Bibliothek pygame-vlc oder opencv-python zum Abspielen von Videos im Pygame-Fenster.

Beispiel mit pygame-vlc:

import vlc
import pygame

def play_intro_video(win, video_path):
    instance = vlc.Instance()
    player = instance.media_player_new()
    media = instance.media_new(video_path)
    player.set_media(media)
    player.set_xwindow(win.get_window_id())  # Für Linux, für Windows/Mac ggf. anpassen
    player.play()
    # Warte bis das Video fertig ist oder eine Taste gedrückt wird
    playing = True
    while playing:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN or event.type == pygame.QUIT:
                player.stop()
                playing = False
        pygame.time.wait(100)
  • Das Video kann z.B. als intro.mp4 im Projektordner liegen.
  • Nach dem Intro kannst du wie gewohnt den Titelbildschirm anzeigen.
  • Für Windows/Mac kann die Fenster-ID Methode abweichen, siehe Doku von pygame-vlc.

Munition für den Spieler und Anzeige als Counter

  • So fügst du dem Spieler eine Munition-Variable hinzu und zeigst sie als Counter im Spiel an:

1. Munition im Player anlegen:

  • Ergänze die Player-Klasse um ein Attribut, z.B.:
class Player:
    def __init__(self, x, y, image):
        self.x = x
        self.y = y
        self.image = image
        self.ammo = 10  # Startwert für Munition
        # ...

2. Munition beim Schießen verringern:

if player.ammo > 0:
    bottles.append(TapWater(player.x, player.y, player.dir))
    player.ammo -= 1
else:
    print("Keine Munition!")

3. Munition beim Berühren eines Trinkbrunnens auffüllen:

MAX_AMMO = 10
# ...
if player_rect.colliderect(brunnen_rect):
    player.ammo = MAX_AMMO

4. Munition als Counter im HUD anzeigen:

  • Im Haupt-Draw-Loop nach dem Zeichnen der Spielfläche:
font = pygame.font.SysFont(None, 32)
ammo_text = font.render(f"Wasser: {player.ammo}", True, (0, 0, 255))
WIN.blit(ammo_text, (20, 20))
  • So sieht der Spieler immer, wie viel Munition noch übrig ist!