image image


Tutorial: Spieleprogrammierung mit TigerJython und GameGrid

Die Klassenbibliothek GameGrid ist eine der bei TigerJython mitgelieferten Bibliotheken und sie ist – wie der Name schon andeutet – für die Spieleprogrammierung gedacht. Da sie ursprünglich in Java geschrieben wurde, konnte sie leicht in TigerJython eingebunden werden. Sie muß mit

import gamegrid as gg

eingebunden und mit

window = gg.GameGrid(WIDTH, HEIGHT, 1, None, "images/background.png", False)
window.setBgColor(161, 214, 231)
window.setTitle("Mein Aquarium")

initialisiert werden. Dabei stehen die ersten beiden Parameter für die Höhe und Breite des Spielfeldes, mit dem dritten Parameter wird die Gitterbreite (in Pixeln) übergeben, der vierte Parameter gibt an, ob das Gitter angezeigt werden soll, im vierten Parameter kann ein Hintergrundbild mitgegeben werden und der fünfte Parameter legt fest, ob unterhalb des Spielfeldes eine Statusleiste angezeigt werden soll. Für das Setzen einer Hintergrundfarbe wie auch die Angabe eines Titels in der Titelzeile gibt es – wie obiger Codeausschnitt zeigt, jeweils eigene Methoden.

image

Das von mir erstellte Hintergrundbild zeigt nur den Boden des Aquariums an, der Rest ist transparent. Daher mußte ich dem Programm noch eine hübsche, hellblaue Hintergrundfarbe spendieren.

Der Ursprung des Koordinatensystems eines GameGrid-Fensters ist übrigens – wie allgemein üblich – die obere, linke Ecke. Somit kenne ich bis jetzt mindestens drei verschiedene Koordinatensysteme in TigerJython: Beim Turtle-Modul gturtle liegt der Nullpunkt in der Mitte des Fensters, das Graphik-Modul gpanel setzt den Ursprung des Koordinatensystems in die linke, untere Ecke und nun GameGrid, das den Ursprung in die eigentlich übliche, linke, obere Ecke setzt. Für dieses Durcheinander gibt es vermutlich nur historische Erklärungen1.

Das GameGrid-Fensters besitzt drei wichtige Methoden:

window.setSimulationPeriod(20)
window.show()
window.doRun()

mit setSimulationPeriod(ms) wird die Zeit (in Millisekunden) gesetzt, in der das Fenster neu gezeichnet werden soll, mit show() wird es angezeigt und doRun() ruft die Methode act() auf, die alle von Actor erbenden Klassen mit Leben füllen sollten2. Also habe ich erst einmal ein Klasse Fish geschrieben, die von Actor erbt und die Methode act() mit Leben füllt:

class Fish(gg.Actor):
    
    def __init__(self, imPath):
        gg.Actor.__init__(self, imPath)
        self.speed = randint(1, 2)
    
    def act(self):
        self.move(self.speed)
        if self.getX() > WIDTH + 30:
            self.reset()
        
    def reset(self):
        self.setX(randint(-270, -30))
        self.setY(randint(30, HEIGHT - 94))

Dem Konstruktor muß ein Pfad zu einer Bilddatei, die den Actor auf dem Monitor darstellen soll, mitgegeben werden, außerdem bekommt jeder Fisch zufällig eine Geschwindigkeit von eins oder zwei zugewiesen. Die Methode act() bewegt den Fisch mit der angegeben Geschwindigkeit (in Pixeln) nach rechts und falls er den rechten Rand des Spielefensters verläßt, wird er mit der Methode reset() an eine zufällige, neue Position links außerhalb des Spielfeldes teleportiert.

Jetzt müssen im Hauptprogramm eigentlich nur noch ein paar Fische erzeugt werden. Das geht mit Pythons Listen recht einfach:

fishes = []
for _ in range(NFISHES):
    fishes.append(Fish("images/fish" + str(randint(1, 4)) + ".png"))
    window.addActor(fishes[_], gg.Location(randint(-270, -30), randint(30, HEIGHT - 94)))

Ich habe vier verschiedene Fisch-Bilder, die ich – wie auch den Boden des Aquariums – in dem hier im Blog Kritzelheft schon häufig erwähnten, unerschöpflichen, freien (CC0 1.0 Universal) Fundes von Kelly.nl entnommen habe. Die Bilder heißen fish1.png bis fish4.png und werden zufällig einem Fisch zugewiesen, der dann mit den gleichen Befehlen wie auch in der Methode reset() links außerhalb des Bildschirmfensters plaziert wird. Und dann geht’s los.

Der Vollständigkeit halber hier das komplette Programm. Es ist wirklich sehr kurz und kein Hexenwerk:

import gamegrid as gg
from random import randint

WIDTH = 640
HEIGHT = 480
NFISHES = 7  # Anzahl der Fische

class Fish(gg.Actor):
    
    def __init__(self, imPath):
        gg.Actor.__init__(self, imPath)
        self.speed = randint(1, 2)
    
    def act(self):
        self.move(self.speed)
        if self.getX() > WIDTH + 30:
            self.reset()
        
    def reset(self):
        self.setX(randint(-270, -30))
        self.setY(randint(30, HEIGHT - 94))

window = gg.GameGrid(WIDTH, HEIGHT, 1, None, "images/background.png", False)
window.setBgColor(161, 214, 231)
window.setTitle("Mein Aquarium")

fishes = []
for _ in range(NFISHES):
    fishes.append(Fish("images/fish" + str(randint(1, 4)) + ".png"))
    window.addActor(fishes[_], gg.Location(randint(-270, -30), randint(30, HEIGHT - 94)))

window.setSimulationPeriod(20)
window.show()
window.doRun()

Denn Quellcode wie auch die verwendeten Bilder findet Ihr in meinem GitLab-Repositorium zu TigerJython.

TigerJython erinnert mit seiner eigenen IDE sehr stark an Processing(.py), allerdings verfolgen die mitgelieferten Bibliotheken andere Ziele. Doch auch wenn sie mehr auf den Lernbereich ausgerichtet sind, soll das nicht heißen, daß man mit TigerJython keine sinnvollen Anwendungen programmieren kann. Und auf jeden Fall macht das Programmieren mit TigerJython Spaß.

  1. Die Logo-Schildkröte startete schon seit Seymor Paperts Zeiten in der Mitte des Fensters und gpanel wurde vermutlich ursprünglich entwickelt, um mathematische Funktionen zeichnen zu lassen. 

  2. In Actor selber ist die Methode leer. 


(Kommentieren) 

image image



Über …

Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter Rentner, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!

Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.

Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.

Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.


Werbung


Werbung


image  image  image
image  image  image


image