Skip to content

Pygame Zero

Simulation

Im letzten Schuljahr haben wir bereits ein kleines Spiel mit Pygame Zero programmiert. Wir können Pygame Zero aber auch wunderbar für die grafische Darstellung unserer Simulation verwenden.

Als Wiederholung programmieren wir eine animierte Schneefall-Szene: Ein winterliches Hintergrundbild und Schneeflocken die herunterfallen.

Vorbereitung

Aufgabe: Vorbereitung

Lade die Vorlage in der verlinkten ZIP-Datei herunter:

Entpacke die Datei und kopiere den Inhalt in deine Informatik-Ordner – beachte dabei dass die Struktur mit dem Unterverzeichnis images bestehen bleibt!

mehr: Tipp Windows

Unter Windows meint man eine ZIP-Datei sei ein normaler Ordner. Dies ist jedoch nicht wirklich so! Wenn man die Python-Datei direkt aus der ZIP-Datei startet, so werden z.B. die benötigten Bilder im Unterordner `images nicht gefunden. Am Besten gehst du wie folgt vor:

  • Öffne die ZIP-Datei mit einem Doppelklick
  • markiere den gesamten Inhalt (mit Ctrl + A)
  • kopiere diesen in die Zwischenablage (mit Ctrl + C)
  • Gehe zu deinem Informatikordner
  • Erstelle einen neuen Ordner Schneefall und öffne diesen
  • Füge den Inhalt aus der Zwischenablage ein (mit Ctrl + V)

Wenn du nun die Vorlage Schneefall.py öffnest, findest du folgenden Code:

py
import pgzrun
import random

def draw():
    hintergrund.draw()

WIDTH = 1350
HEIGHT = 900
hintergrund = Actor("winter_1.jpg")

pgzrun.go()

Es wird ein Hintergrundbild gezeichnet in ein Pygame Zero-Fenster welches von den Dimensionen gerade diesem Bild entspricht.

Aufgabe

Starte das Programm – das Bild sollte angezeigt werden. Wenn nicht, dann stimmt etwas mit dem Vorbereiten nicht, z.B. findet Pygame Zero die Bilder nicht, weil der Unterordner images falsch platziert ist.

Nun kannst du das Hintergrundbild wechseln. Es hat ein zweites Bild winter_2.jpg. Versuche es mal damit.

Entscheide dich, ob du mit dem zweiten Bild weitermachen möchtest. Sonst stellst du wieder zurück.

Zusatzaufgabe

Suche ein eigenes Hintergrundbild. Achte aber auf die Grösse und passe die Grösse des Pygame-Zero-Fensters entsprechend an.

Schneeflocke

py
import pgzrun
import random

def draw():
    hintergrund.draw()
    flocke.draw()

WIDTH = 1350
HEIGHT = 900
hintergrund = Actor("winter_1.jpg")

flocke = Actor("schneeflocke_1.png")
flocke.x = 200

pgzrun.go()
py
import pgzrun
import random

def draw():
    hintergrund.draw()
    flocke.draw()
    
def update():
    flocke.y = flocke.y + 1

WIDTH = 1350
HEIGHT = 900
hintergrund = Actor("winter_1.jpg")

flocke = Actor("schneeflocke_1.png")
flocke.x = 200

pgzrun.go()
py
import pgzrun
import random

def draw():
    hintergrund.draw()
    flocke.draw()
    
def update():
    flocke.y = flocke.y + 1
    if flocke.y > HEIGHT:
        flocke.y = 0

WIDTH = 1350
HEIGHT = 900
hintergrund = Actor("winter_1.jpg")

flocke = Actor("schneeflocke_1.png")
flocke.x = 200

pgzrun.go()
schneefall_2a
wir fügen eine erste Flocke als Actor hinzu, positionieren und zeichnen sie
schneefall_2b
wir fügen die update-Funktion hinzu. Diese wird immer vor dem Neu-Zeichen des Bildes aufgerufen und setzt unsere Schneeflocke auf eine neue Position (wird um einen Pixel nach unten verschoben)
schneefall_2c
damit die Schneeflocke nicht unten am Bild verschwindet, «recyclen» wir sie mit dem eingebauten if und stellen sie einfach wieder oben hin, damit sie neu herunterfallen kann

Zufall

Die Schneeflocke soll zufällig positioniert werden, d.h. wir wählen ihre Koordinaten zufällig. Dazu verwenden wir das Modul random. Mit der Funktion randrange können zufällige ganze Zahlen in einem bestimmten Bereich erzeugt werden:

python
import random

würfel = random.randrange(1,7)
print(würfel)

Position

Beim Erzeugen der Schneeflocke soll diese komplett zufällig positioniert werden. Wir wählen also die x-Koordinate zwischen 0 und der Breite des Fensters WIDTH sowie die y-Koordinate zwischen 0 und der Höhe des Fensters HEIGHT.

In der Update-Funktion wählen wir nur die x-Koordinate zufällig. Die y-Koordinate wird ja auf 0 gesetzt.

py
import pgzrun
import random

def draw():
    hintergrund.draw()
    flocke.draw()
    
def update():
    flocke.y = flocke.y + 1
    if flocke.y > HEIGHT:
        flocke.x = random.randrange(0, WIDTH)
        flocke.y = 0        

WIDTH = 1350
HEIGHT = 900
hintergrund = Actor("winter_1.jpg")

flocke = Actor("schneeflocke_1.png")
flocke.x = random.randrange(0, WIDTH)
flocke.y = random.randrange(0, HEIGHT)

pgzrun.go()

Bild

Im Bilder-Ordner hat es 3 unterschiedliche Schneeflocken-Bilder. Hier wollen wir auch zufällig eines auswählen. Dazu können wir die Choice-Funktion verwenden. Diese wählt zufällig ein Element aus einer Liste:

python
import random

seiten = ["kopf", "zahl"]
münze = random.choice(seiten)
print(münze)

Wir fügen also eine Liste mit den Dateinamen der Schneeflocken-Bilder ein und wählen unsere Flocke zufällig:

py
import pgzrun
import random

def draw():
    hintergrund.draw()
    flocke.draw()
    
def update():
    flocke.y = flocke.y + 1
    if flocke.y > HEIGHT:
        flocke.x = random.randrange(0, WIDTH)
        flocke.y = 0        

WIDTH = 1350
HEIGHT = 900
bilder = ["schneeflocke_1.png", "schneeflocke_2.png", "schneeflocke_3.png"]

hintergrund = Actor("winter_1.jpg")

bild = random.choice(bilder)
flocke = Actor(bild)
flocke.x = random.randrange(0, WIDTH)
flocke.y = random.randrange(0, HEIGHT)

pgzrun.go()

Liste von Schneeflocken

Um eine grössere Anzahl Schneeflocken zu simulieren brauchen wir natürlich eine Liste. Diese erstellen wir auf Zeile 22. Ab Zeile 24 erstellen wir 100 Schneeflocken und hängen sie mit append der Liste an (Zeile 29).

Nun haben wir eine Liste mit Schneeflocken. Diese müssen wir in der update- (Zeile 10) und der draw-Methode (Zeile 6) entsprechend Element-um-Element durchgehen – es sollen ja alle Flocken runterfallen und auch gezeichnet werden. Der vorherige Code für die einzelne Flocke kommt nun eingeschoben im for-Block vor und wird somit für jede Flocke der Liste ausgeführt:

py
import pgzrun
import random

def draw():
    hintergrund.draw()
    for flocke in flocken:
        flocke.draw()
    
def update():
    for flocke in flocken:
        flocke.y = flocke.y + 1
        if flocke.y > HEIGHT:
            flocke.x = random.randrange(0, WIDTH)
            flocke.y = 0        

WIDTH = 1350
HEIGHT = 900
bilder = ["schneeflocke_1.png", "schneeflocke_2.png", "schneeflocke_3.png"]

hintergrund = Actor("winter_1.jpg")

flocken = []

for i in range(100):
    bild = random.choice(bilder)
    flocke = Actor(bild)
    flocke.x = random.randrange(0, WIDTH)
    flocke.y = random.randrange(0, HEIGHT)
    flocken.append(flocke)

pgzrun.go()

Zusatzaufgabe: Erweiterungen

Es folgen einige Ideen zur Umsetzung von Erweiterungen:

  • lasse die verschieden grossen Schneeflocken verschieden schnell fallen: Grössere schneller, kleinere langsamer. Das ergibt einen Parallax-Effekt (man meint die grösseren und schnelleren seien weiter vorne als die langsamen kleineren)
  • Finde weitere Grafiken (z.B. andere Schneeflocken, ev. mit Transparenz, oder doch noch einen anderen Hintergrund, oder einige Sterne, …)
  • Wind: die Schneeflocken fallen nicht ganz gerade, oder aber sie fallen unregelmässig oder aber sogar: sie werden durch den Mauscursor beeinflusst

Gymnasium Kirchenfeld, fts