Bevor du mit Teil 2 anfängst, erledige alle Aufgaben aus Teil 1.
In den folgenden Aufgaben gebe ich keine genauen Hinweise mehr, wo du Bilder oder Dateien speichern sollst oder wo genau der Code geschrieben wird.
Das Spiel baut aufeinander auf, daher ist es wichtig, dass du nach jeder Codeänderung die Python-Datei script.py
ausführst und testest, ob das Spiel tatsächlich wie erwartet funktioniert.
Speichere deine Lösungen weiterhin in der Datei lsg_nachname.txt
und achte darauf, dass die Lösungen zu den Aufgaben unter den richtigen Aufgabennummern stehen.
Es ist sehr wichtig, das Folgende zu verstehen: Jede Datei hat eine Erweiterung, die ihren Typ angibt. Hier sind einige Beispiele:
venusaur.png
→ Bilddatei im PNG-Formatlsg_nachname.txt
→ Textdatei im TXT-Formateating_sounds.ogg
→ Audiodatei im OGG-FormatPygame Zero unterstützt Bilddateien in den Formaten .png
, .gif
und .jpg
.
Empfehlung: Verwende das PNG-Format. Es bietet eine hohe Bildqualität und unterstützt Transparenz, was besonders für Spiele nützlich ist.
Pygame Zero kann Audiodateien in den Formaten .wav
und .ogg
laden. Wie schon erwähnt, funktioniert es auf manchen Rechnern überhaupt nicht. Ich suche nach einer Lösung.
WAV: Gut geeignet für kleine
Soundeffekte (z. B. Klickgeräusche).
OGG: Ein komprimiertes Format, ideal für längere Audioinhalte wie Musik oder Hintergrundklänge.
Pygame Zero unterstützt das MP3-Format nicht.
Achte darauf, die Dateiformate bewusst auszuwählen, damit dein Spiel optimal funktioniert.
Lade das Bild herunter. Alternativ kannst du selbst nach passenden PNG-Hintergrundbildern suchen (z. B. auf Open Game Art).
Die Datei grass.png
hat eine Größe von 800 x 600 Pixeln. Wenn die Höhe oder Breite deines Spielfensters größer als 800 bzw. 600 ist, werden alle Bereiche, die nicht vom Hintergrundbild abgedeckt sind, in Schwarz angezeigt.
Du kannst die Bildgröße mithilfe eines Online-Photo-Editors, z. B. Photopea, anpassen oder Bilder zuschneiden.
grass.png
) zu deinem Spiel hinzu. Erstelle einen Actor für das Bild und nenne ihn bg
(kurz für background). Zeichne das Hintergrundbild mithilfe der draw
-Funktion. Überlege: Brauchst du noch screen.clear()
? Begründe, warum oder warum nicht.Jetzt wird es spannender: Wir fügen einen Gegner hinzu.
Lade diese Datei herunter. Alternativ kannst du Pokémon-Sprites hier finden oder einfach googeln. Achte darauf, dass du gezielt nach Bilddateien suchst, die speziell für 2D-Spiele erstellt wurden, damit sie optimal aussehen. Gib dazu Begriffe wie „Pokémon Sprite PNG“ oder „Dragon Sprite PNG“ ein.
Sprites sind ein Fachbegriff aus der Videospielentwicklung und bezeichnen kleine Bilder, die in Videospielen verwendet werden.
Füge einen Gegner zu deinem Spiel hinzu, indem du einen Actor erstellst und ihn enemy
nennst. Positioniere den Gegner an einer beliebigen Stelle auf dem Bildschirm und teste, ob der Code wie erwartet funktioniert.
Ergänze den folgenden Code in deinem Spiel:
def update():
# anderer Code
if enemy.x < player.x:
enemy.x += 1
if enemy.x > player.x:
enemy.x -= 1
Teste den Code. Was tut der Gegner, wenn seine x-Koordinate kleiner als die des Spielers ist? Was passiert, wenn die x-Koordinate des Gegners größer als die des Spielers ist?
Der Gegner folgt dem Spieler derzeit nur entlang der x-Achse. Erweitere den Code, damit der Gegner dem Spieler auch entlang der y-Achse folgt.
Lade diese Datei herunter. Dein Code soll ein Geräusch abspielen, wenn der Gegner den Spieler berührt. Nutze die Methode colliderect()
, um Kollisionen zu erkennen. Falls die Datei nicht abgespielt werden kann, lasse stattdessen print("hurt")
im Terminal ausgeben.
Setze den Punktestand auf null zurück, wenn der Gegner den Spieler berührt.
Du kannst deinem Spiel zusätzliche Items wie ein Edelstein hinzufügen. Oder z. B. Pokémon-Items, die du hier findest.
Ein Timer misst die Spielzeit und kann später verwendet werden, um verschiedene Schwierigkeitsstufen zu steuern.
Erstelle eine timer
Variable (vgl. Aufg. 19).
Erhöhe ihren Wert in der update
-Funktion mit:
timer += 1 / 60
Zeige den Wert auf dem Bildschirm an.
Warum verwenden wir += 1/ 60
statt += 1
?
Erkläre den Unterschied.
Der Timer zeigt aktuell lange Dezimalzahlen an.
Ersetze str(timer)
durch:
str(round(timer, 2))
Was macht die Funktion round()
?
Was bedeutet die Zahl 2
im Argument?
Was passiert, wenn du nur round(timer)
schreibst?
Jetzt sollen mehrere Items zufällig auf dem Bildschirm erscheinen. Dies ist etwas anspruchsvoller zu programmieren, da wir Listen verwenden, um die Items zu verwalten.
Füge folgende Codezeile außerhalb der draw
- und update
-Funktionen ein:
items = []
Lade dieses Bild herunter oder suche selbst nach einem passenden Bild.
Erweitere die update
-Funktion mit folgendem Code, um zufällig neue Items zu erstellen und sie zu verwalten:
def update():
# anderer Code
if len(items) < 3 and random.randint(0, 100) == 0:
item = Actor("candy")
item.x = random.randint(0, WIDTH)
item.y = random.randint(0, HEIGHT)
items.append(item)
for x in items[:]: # Statt nur for x in items
if x.colliderect(player):
score += 5
items.remove(x)
print("Candy collected!")
Ergänze diesen Code in der draw
-Funktion, um alle Items auf dem Bildschirm darzustellen:
def draw():
# anderer Code
for x in items:
x.draw()
Teste den Code, um sicherzustellen, dass er ohne Fehlermeldungen läuft. Achte dabei immer auf die richtige Einrückung.
Was macht die Bedingung len(items) < 3
in der if
-Anweisung? Was bedeutet len
? Was passiert, wenn du len(items) < 3
durch len(items) < 10
oder len(items) < 20
ersetzt?
Was prüft random.randint(0, 100) == 0
in der if
-Anweisung? Was passiert, wenn du stattdessen random.randint(0, 20) == 0
schreibst? Erscheinen die Items häufiger? Warum?
Erkläre die folgenden Codezeilen:
item.x = random.randint(0, WIDTH)
item.y = random.randint(0, HEIGHT)
Was machen diese Zeilen, und warum sind sie nötig?
Erkläre die folgende Codezeile:
items.append(item)
Was macht diese Zeile, und wie verändert sie die Liste items
?
Aus technischen Gründen, auf die ich hier nicht näher eingehen werde, müssen wir in der for
-Schleife for x in items[:]
schreiben, anstatt nur for x in items
.
Erkläre, was im Code innerhalb der for
-Schleife passiert.
Erkläre die folgenden Zeilen:
for x in items:
x.draw()
Was bewirken diese Zeilen? Würde sich etwas ändern, wenn wir anstelle von x
die Variablen y
oder bobo
verwenden?
Wenn du mit den obigen Aufgaben fertig bist, erweitere dein Spiel selbst weiter. Schreibe deinen Code jedoch in eine separate Datei test.py
, damit der Basiscode in der Datei script.py
, in der du die Aufgaben machst, unverändert für zukünftige Aufgaben bleibt.
Lass dich von der Webseite A Posteriori inspirieren!