lehrkraefte:snr:informatik:glf22:python:snake

This is an old revision of the document!


Pygame: a ball game and snake

Pygame ist eine Python-Library zur Spiele-Programmierung.

Ziele dieses Abschnitts:

  • einen groben Eindruck bekommen, wie ein Snake-Programm in Python funktioniert.

Selbst solch ein Programm zu schreiben ist deutlich schwieriger und braucht vor allem viel Übung im Programmieren.

Hist ist ein Link zu einem in pygame programmierten Spiel (bitte nur kurz ausprobieren).

Falls das Programm bei dir nicht läuft:

Falls das Programm bei dir nicht läuft:

Es könnte sein, dass pygame nicht installiert ist: Installation mit pip install pygame in der “command line”/“cmd”/Eingabeaufforderung/Befehlszeile.

Alternativ kannst du online programmieren:

Lösche das Programm dort und ersetze es durch das Programm “ball-game.py”.

Die Tastatursteuerung ist online wohl etwas langsam.


Der Spieler (grünes Quadrat) gewinnt ein Leben, wenn er den purpurfarbenen Ball fängt, und verliert zwei Leben, wenn der Ball an der rechten Seite des Spielfeldrandes reflektiert wird. Man startet am Anfang mit 10 Leben, gewinnt bei 20 Leben und verliert bei 0 Leben.

Das grüne Quadrat wird mit den Pfeiltasten gesteuert, jedoch hat der Programmierer dies nicht wie erwünscht hinbekommen. Auch bewegt sich der Ball nicht wie beabsichtigt.

Die gewünschte Steuerung mit den Pfeiltasten ist wie folgt.

  • Jedes Drücken einer Pfeiltaste bewegt das Quadrat um ein Feld in die entsprechende Richtung, mit folgenden Ausnahmen:
  • Das Quadrat kann das Spielfeld rechts und links nicht verlassen und stösst dort an die Ränder an.
  • Wenn es das Spielfeld oben verlässt, kommt es sofort an derselben x-Koordinate unten in das Spielfeld und umgekehrt.

Erwünschte Bewegung des Balls:

  • An allen Seiten des Spielfelds ausser der linken soll der Ball normal reflektiert werden.
  • An der linken Seite soll das bereits programmierte zufällige Verhalten bestehen bleiben.

Beachte: Für die folgenden Aufgaben musst du nur einen geringen Teil des Programms verstehen! Was du wissen musst, ist jeweils in den Hinweisen erläutert.

Teilaufgabe 1

Hilf dem Programmierer, die gewünschte Steuerung mit den Pfeiltasten zu erreichen (dabei sollst du den Ball vollständig ignorieren, es geht nur um das grüne Quadrat).

  • (1) Kümmere dich darum, dass jede der vier Pfeiltasten das Quadrat um genau ein Feld in die gewünschte Richtung bewegt.
  • (2) Kümmere dich darum, dass das Quadrat nicht aus dem Spielfeld verschwindet, sondern das oben beschriebene Verhalten zeigt.

Dafür musst du nur etwa 20 Zeilen ab Zeile 176 ändern, das gesamte restliche Programm bleibt unverändert (vgl. Kommentar in Zeile 173).

Hinweise

Hinweise

Die gesamte if-elif-…-Struktur kann unverändert bleiben.

Die y-Achse des “Spielfeld-Koordinatensystems” zeigt nach unten! Der Ursprung des Koordinatensystems ist in der linken oberen Ecke des Spielfeldes.

Die aktuelle Position des grünen Quadrats ist in der Variablen spieler gespeichert:

  • spieler.x ist seine $x$-Koordinate,
  • spieler.y ist seine $y$-Koordinate.

Überlege zuerst, wie du diese Koordinaten bei den jeweiligen Pfeiltasten verändern musst.

Für das gewünschte Verhalten an den Rändern des Spielfelds: Die Koordinaten des Spielfelds gehen in

  • $x$-Richtung von 0 bis MAXX und in
  • $y$-Richtung von 0 bis MAXY.

Teilaufgabe 2

Hilf dem Programmierer, das gewünschte Reflexionsverhalten des Balles zu erreichen.

Dafür musst du nur etwa 10 Zeilen ab Zeile 220 anpassen, das gesamte restliche Programm bleibt unverändert (vgl. Kommentar in Zeile 217 - Zeilenangaben beziehen sich auf das “Originalprogramm”).

Hinweis

Hinweis

Beobachte zuerst genau, an welchen der drei Spielfeldränder (oben, rechts, unten) das Reflexionsverhalten falsch ist.

Die if-Bedingungen können und sollen so stehen bleiben.

Die aktuelle Position des Balls ist in der Variablen ball gespeichert:

  • ball.x ist seine $x$-Koordinate,
  • ball.y ist seine $y$-Koordinate.

Während des Spielablaufs wird die sogenannte “game loop” (beginnend in Zeile 140 und endend in Zeile 236) immer wieder durchlaufen (ca. 40 Mal pro Sekunde). Die Variable bewegungsrichtung_ball hat ebenfalls zwei Komponenten:

  • bewegungsrichtung_ball.x ist seine x-Koordinate,
  • bewegungsrichtung_ball.y ist seine y-Koordinate.

In jedem Durchlauf der “game loop” wird (in Zeile 215) dieser Vektor zur Position ball des Balls hinzuaddiert ($x$-Koordinate zu $x$-Koordinate, $y$-Koordinate zu $y$-Koordinate, wie bei der Addition von Kräften in der Physik bzw. der Vektoraddition in der Mathematik). Deswegen wirkt die Bewegung des Balls kontinuierlich.

Passe nun jeweils die Zeilen nach den drei if-Zeilen an; zwei Programm-Zeilen können eingespart werden.

Teilaufgabe 3

Schau dir zuerst die “game loop” (Zeilen 140 bis 236) und dann das Hauptprogamm (beginnend in Zeile 120) an und versuche, möglichst viel zu verstehen. Wer will, kann sich natürlich auch den Rest des Programms anschauen.

Teilaufgabe 4

Viel Spass beim Spielen! Mit der nun einfacheren Bedienung hat man bessere Gewinnchancen! - Aber bitte nicht zu lange spielen.

Bonusaufgaben

(teilweise vielleicht auch eine gute Idee, diese in Zukunft einzubauen)

  • Steuere eine zweite farbige Box mit den Tasten a, s, d, w. Was passiert bei einer Kollision der beiden Spieler?
  • Ändere die Steuerung (vermutlich nicht so leicht; braucht u.a. KEYUP als mögliches key event):
    • Wenn man auf einer Pfeiltaste bleibt, bewegt sich das grüne Quadrat immer weiter in die entsprechende Richtung.
    • Das Quadrat bewegt sich kontinuierlich (ähnlich wie der Ball). Das Drücken einer Pfeiltaste ändert die Richtung. (Diese Art der Steuerung werden wir bei Snake verwenden.)

Um Snake zu programmieren, kommt man kaum um Listen herum, denn die Positionen, an denen sich die “Körperglieder” der Schlange befinden, speichert man sinnvollerweise in einer solchen Liste.

Aufgabe: Beginne, den Abschnitt Listen des Programmierkurses über Listen zu lesen. Wer bis zur Modifikation von Listen kommt, weiss mehr, als wir für Snake brauchen werden!

Das hier verborgene Programm enthält alles über Listen, was in Snake benötigt wird

Das hier verborgene Programm enthält alles über Listen, was in Snake benötigt wird

listen-demo.py
# Beispiel 1:
# Top 5 der Vornamen in der italienschen Schweiz 2021 laut BFS, https://babynames-stat.ch/de/index.html
namens_liste = ['Leonardo', 'Alessandro', 'Liam', 'Noah', 'Tommaso']
print(namens_liste)
print(namens_liste[3])
print(namens_liste[0])
print("Liam" in namens_liste)
print("Luca" in namens_liste)
print(len(namens_liste))
for name in namens_liste:
    print('Mi chiamo ' + name + '.')
print(len(namens_liste))
namens_liste.insert(0, 'Nathan')
namens_liste.pop()
print(namens_liste)
print(namens_liste[2:6])
 
# Beispiel 2:
notenliste=[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]
summe = 0
for note in notenliste:
    summe = summe + note
print(f'Durchschnitt = {summe / len(notenliste)}')
 
# Beispiel 3:
from random import *
liste_der_wuerfe = []
while liste_der_wuerfe[0:2] != [0, 0]:
    liste_der_wuerfe.insert(0, randrange(2))
    print(liste_der_wuerfe)

Ausserdem sollte man verstehen, warum eine Liste die naheliegende Datenstruktur für Snake ist.

Hist ist ein Link zu einem in pygame programmierten snake-ähnlichen Spiel (bitte nur kurz ausprobieren).

Korrigiere dieses Programm, so dass es dem üblichen Snake ähnelt:

  • Statt mit den Tasten r, t, f, g soll die Steuerung wie gewohnt mit den Pfeiltasten funktionieren.
  • Wenn die Schlange einen Apfel frisst, soll die unter dem Spielfeld angezeigte Variable gefressene_aepfel um eins erhöht werden.
  • Pro gefressenem Apfel soll die Länge der Schlange um eins wachsen.
  • Wenn die Schlange gegen eine der vier Wände des Spielfelds läuft, endet das Spiel.

Hinweis: Es sind nur wenige Änderungen innnerhalb der “game loop” (ab Zeile 171) nötig.

Überlege dir, wie man das Spiel weiterentwickeln könnte.

einige Idee

einige Idee

  • Füge ein Hindernis ein: Die Schlange stirbt, wenn sie dagegen fährt. Das Hindernis könnte sich auch bewegen (hin und her oder gar Richtung Schlange).
  • Programmiere eine zweite Schlange, die sich etwa mit den Tasten a, s, d, w steuern lässt, so dass ihr gegeneinander spielen könnt (Achtung, das q für den Abbruch ist gefährlich nah an diesen Tasten.) Wer verschlingt mehr Äpfel? Zeige den jeweiligen Punktestand an. Was passiert und wer ist schuld, wenn es eine Kollision gibt? Endet das Spiel oder muss man einen Apfel abgeben oder wird man länger/kürzer? Vielleicht gibt es auch gar keine Äpfel mehr und es geht nur darum, den Gegner zu einer Kollision zu zwingen. Eventuell mehrere Runden hintereinander spielen.
  • Die Schlange benötigt Energie für's Herumschleichen; zum Beispiel könnte sie alle 100 Schritte einen Apfel verlieren.
  • Statt einem Apfel könnte es mehrere Äpfel geben (die nur eine begrenzte Zeit lang existieren). Hier wäre es vermutlich sinnvoll, eine Liste mit den aktuellen Apfelpositionen zu verwenden.
  • Es könnte auch mehrere Hindernisse geben oder mehrere Schlangen.
  • Verschiedene Level einführen.
  • Spielen übers Netzwerk?

... wenn du eigene Bilder oder Sounds integrieren willst

Vorbereitet ist das Programm so, dass du

  • Bilder für den Hintergrund oder
  • Bilder für den Apfel und den Schlangenkopf oder
  • Sounds für Spielende und Apfelfressen

leicht einbinden kannst (du kannst beispielsweise nur ein Hintergrundbild einbinden).

Dazu musst du geeignete Dateien bereitstellen (am besten in demselben Verzeichnis wie das Programm) und

  • in der Funktion lade_bilder_und_sound die entsprechenden Dateinamen (eventuell inklusive Pfad) angeben und
  • die booleschen Konstanten EINFARBIGER_HINTERGRUND (Hintergrund), BOXEN_STATT_BILDER (Apfel und Schlangenkopf) und MIT_SOUND (Spielende und Apfelfressen) entsprechend anpassen, d.h. auf False bzw. False bzw.True setzen.
  • lehrkraefte/snr/informatik/glf22/python/snake.1674776481.txt.gz
  • Last modified: 2023/01/27 00:41
  • by Olaf Schnürer