Mini-Spiel
Mittlerweile haben wir viele Programmiergrundkenntnisse erarbeitet und können mit den einzelnen Konzepten schrittweise grössere Programme konstruieren. Als Nächstes wollen wir ein kleines Spiel entwickeln ("Mini-Snake").
Vorlage
Vorlage ausführen & studieren
Verwende nun das Programm TigerJython, welches wir einmal installierten. (Auf dem iPad musst du WebTigerJython verwenden.)
Spiel Vorlage
Kopiere das folgende Programm nach TigerJython und führe es aus. Was passiert?
from gpanel import *
makeGPanel(-60, 60, -60, 60)
text(-58, -58, "Drücke W, A, S, D!")
x = 0
y = 0
setColor("green")
# Endlosschleife
# ähnlich wie for _ in range(9999999...):
while True:
if kbhit():
keyCode = getKeyCode()
buchstabe = chr(keyCode)
if buchstabe == "W":
y += 2
if buchstabe == "S":
y -= 2
if buchstabe == "A":
x -= 2
if buchstabe == "D":
x += 2
move(x, y)
fillCircle(1)
delay(10) # 10 ms warten
Question
Es gibt dabei viele für dich unbekannte Befehle (Prozeduren und Funktionen) und Schlüsselwörter.
Notiere die unbekannten Befehle und mache für jeden Befehl einen Vorschlag, was dabei passieren könnte.
Dazu ist der Name eines Befehls manchmal sehr aufschlussreich. Entweder durch die Bedeutung des Names (leider auf Englisch) oder durch einen Analogieschluss:
from gpanel import *
from gturtle import *
Spielelemente
Question
Welche Spielelemente sind nötig für ein Snake-Spiel? Als Beispiel:
- Wenn die Schlange in sich selbst hineinläuft hat man die Runde/das Spiel verloren.
Notiere dir mindestens drei weitere Ideen dazu.
Grafik-Bibliothek
Wir verwenden für diese Übung nicht mehr die gturtle sondern eine andere Programmierbibliothek für die grafische Ausgabe. Diese Bibliothek heisst GPanel und funktioniert leicht anders als die Schildkröte.
Question
Lies auf dieser Seite nach wie das Koordinatensystem mit GPanel funktioniert.
Event-Loop
flowchart TD
start(["START"])
stop(["STOP"])
Input1[\"Input: Mausbewegung"\]
Input2[\"Input: Tastatureingabe"\]
vorB["Spiel vorbereitung"]
ende["Spiel abschliessen"]
spielState["neuer Spielstand berechnen"]
draw[\"Ausgabe: Spiel zeichnen"\]
AusgabeSpiel[\"Ausgabe: Score"\]
eventLoop{wurde das Spiel beendet?}
start --> vorB
vorB --> eventLoop
eventLoop -->|Ja| ende
eventLoop -->|Nein| Input1
Input1 --> Input2
Input2 --> spielState
spielState --> draw
draw --> eventLoop
ende --> AusgabeSpiel
AusgabeSpiel --> stop
Spiel entwickeln
Schlangenkollision
Als erster Schritt fügen wir folgendes Spielelement hinzu: die Kollision der Schlange mit sich selbst.
Dazu ist die Funktion getPixelColorStr(x, y) nützlich, sie gibt Farbe am Punkt (x, y) als X11-Farbstring zurück.
Mehr Informationen dazu: Referenz für die Zeichnen-Funktionen.
Question
Baue die Funktion getPixelColorStr(x, y) in dem Programm vor dem Aufruf von move ein. Beobachte den Rückgabewert der Funktion, in dem du ihn mit print ausgibst.
Erweitere das Programm so, dass es erkennen kann, ob die Schlange in sich selbst hineinfuhr.
Nützliche weitere Funktionen dazu sind:
| Befehl | Aktion |
|---|---|
| setColor(color) | setzt die Stiftfarbe (X11-Farbstring oder Colortype) |
| fillRectangle(x1, y1, x2, y2) | zeichnet gefülltes Rechteck (Füllfarbe = Stiftfarbe) |
| fill(x, y, color, replacementColor) | füllt geschlossenes Gebiet um Punkt (x, y). color wird durch replacementColor ersetzt (floodfill) |
| break | bricht die aktuelle Schleife ab |
Weitere Elemente
Question
Erweitere das Spiel um die folgenden Spielelementen:
- Spielabbruch bei Kollision
- Ausgabe beim Abbruch: z.B. "Game over*
- Kollision mit der Wand
- Selbstfahrende Schlange
Erweitern
Wandkollision
Question
Erweitere das Spiel um eine Kollision mit den Wänden zu erkennen.
Eigene Erweiterung
Erweitere nun das Spiel mit deinen eigenen Ideen bzw. verändere die bestehenden Elemente nach deinem Geschmack (z.B. Farben, Formen).
Extras
Schriftgrösse
Das Ändern der Schriftgrösse ist etwas kompliziert, man muss ein sogenannter Font Objekt erstellen, welches verschiedene Attribute einer Schrift bestimmt:
| Befehl | Aktion |
|---|---|
| Font(name, style, size) | erzeugt eine 'Schrift' mit gegebenen Namen, Stil und Grösse: name: ein String mit einem dem System bekannten Fontnamen, z.B.. "Times New Roman", "Arial", "Courier". style: einer der Konstanten: Font.PLAIN, Font.BOLD, Font.ITALIC oder einen Kombination davon: Font.BOLD + Font.ITALIC size: ein Integer mit einer auf dem System verfügbaren Font-Grösse (in pixels), z.B. 12, 16, 72 |
Beispiel:
schrift1 = Font("Arial", Font.PLAIN, 54))
schrift1 ist nun eine "Schrift", mit der Schriftart Arial, im Schrittstil PLAIN d.h. normal (alternativ gibt es fett oder kursiv) und der Schriftgrösse 54.
Danach kannst du entweder diese Schrift für alle folgenden Texte verwenden, indem du einmal die globale Schrift festlegst:
font(schrift1)
text(0,0, "Ein Text mit Grösse 54pt")
text(0,0, "Ein Text mit Grösse 54pt", schrift1, "black", "red")