Zum Inhalt

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 *
klingt ähnlich wie welches bekannte Konzept?

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))
Die Variable 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")
Oder in dem du nur diese Schrift für ein 'zeichnenaufruf', dabei muss zusätzlich die Schriftfarbe sowie die Farbe des Hintergrunds angegeben werden.
text(0,0, "Ein Text mit Grösse 54pt", schrift1, "black", "red")