image image


image

Mein kleines, bonbonbuntes Aquarium (in Processing.py)

Wie Ihr Euch vielleicht erinnert, hatte ich ein bonbonbuntes Aquarium vor einigen Monaten schon einmal in TigerJython und der GameGrid-Bibliothek implementiert (hier und hier). Am Sonntag hatte ich dann die Idee, dieses Aquarium auch einmal nach Processing.py zu portieren, auch um herauszufinden, welche Gemeinsamkeiten TigerJython und Pocessing.py besitzen und wo die Unterschiede liegen.

Wie immer bei Processing.py ist der Hauptsketch recht klein geraten, weil die gesamte Programmlogik in der Klasse Fish implementiert wurde:

from random import randint

class Fish():
    
    def __init__(self):
        no = str(randint(1, 7))
        self.imr0 = loadImage("fish" + no + "_r0.png")
        self.iml0 = loadImage("fish" + no + "_l0.png")
        self.imr1 = loadImage("fish" + no + "_r1.png")
        self.iml1 = loadImage("fish" + no + "_l1.png")
        self.reset()
        self.w = self.h = 32
        self.pos = PVector(randint(30, width - 30), randint(10, height - 120))
        self.count = 0
        self.switch = 5
    
    def update(self):
        self.pos.x += self.speed
        self.count -= 1
        if self.count <= 0:
            self.count = self.switch
            if self.im == self.imr0:
                self.im = self.imr1
            elif self.im == self.imr1:
                self.im = self.imr0
            elif self.im == self.iml0:               
                self.im = self.iml1
            elif self.im == self.iml1:
                self.im = self.iml0
        if self.pos.x > width + 2*self.w:
            self.pos.x = randint(width + self.w, width + 2*self.w)
            self.pos.y = randint(10, height - 120)
            self.speed = -randint(1, 3)
            self.im = self.iml0
        elif self.pos.x < -2*self.w:
            self.pos.x = randint(-2*self.w, -self.w)
            self.pos.y = randint(10, height - 120)
            self.speed = randint(1, 3)
            self.im = self.imr0
    
    def show(self):
        image(self.im, self.pos.x, self.pos.y)
    
    def reset(self):
        self.im = self.imr0
        self.speed = randint(-3, 3)
        if self.speed < 0:
            self.im = self.iml1
        elif self.speed == 0:
            self.speed = randint(1, 3)

Man erkennt die ersten Unterschiede: Processing.py fehlen etliche der Annehmlichkeiten, die in TigerJython die Bibliothek GameGrid mit der Superklasse Actor bietet. Weder den in GameGrid automatisierten Wechsel bei der Animation der Sprites noch das einfache Setzen und Zurücksetzen der gespiegelten Sprites kennt Processing.py. Daher mußte ich im Konstruktor statt einem Bild gleich vier Bilder je Fisch laden.

Das setzt sich auch in der update()-Methode fort (vergleichbar der act()-Methode in TigerJython). Sie ist wegen des Fehlens der setHorzMirror()- und der showNextSprite()-Methoden bedeutend umfangreicher als das TigerJython-Äquivalent (und das nicht nur, weil ich das Programm dahingehend ergänzt habe, daß die Fische beim Erreichen der Ränger nun auch die vertikale Position ändern – das betrifft nur die letzte ifelif-Bedingung in update()).

Die reset()-Methode habe ich nur erstellt, weil ich ursprünglich dachte, daß ich sie auch beim Richtungswechsel der Fische verwenden könnte. Da ich mich da aber anders entschieden hatte, hätte sie ebensogut direkt in den Konstruktor (__init__()) implementiert werden können. Ich habe sie dann aber stehen lassen, weil sie vielleicht den Code etwas übersichtlcher gestaltet.

Nun noch das Hauptprogramm:

HEIGHT = 416
NFISHES = 15  # Anzahl der Fische
FPS = 60

fishes = []

def setup():
    global bg
    size(WIDTH, HEIGHT)
    this.surface.setTitle(u"Jörgs kleines, bonbonbuntes Aquarium")
    bg = loadImage("background.png")
    for _ in range(NFISHES):
        fishes.append(Fish())
    frameRate(FPS)
    

def draw():
    background(49, 197, 224) # Himmelblau
    image(bg, 0, 0)
    for fish in fishes:
        fish.show()
        fish.update()

Hier kann man nicht meckern. Es ist kurz und durch die spezielle Konstruktion von Processing(.py) meiner Meinung nach auch übersichtlicher als das TigerJython-Äquivalent. Und damit Ihr die Fische auch in Bewegung sehen könnt, habe ich mit der gleichen Methode wie auch schon bei der letzten Hommage an Bridget Riley ein Video erstellt und auf YouTube hochgeladen:

Doch heißt das jetzt, daß TigerJython für die Spieleprogrammierung besser geeignet ist als Processing(.py)? Ganz so eindeutig fällt die Antwort dann doch nicht aus. Erstens ist mir keine Methode bekannt, mit der man TigerJython-/GameGrid-Skripte in Executables umwandeln kann, also in ausführbare Programme, die ohne TigerJython laufen.1 Dies aber ist in Processing(.py) eingebaut.

Und zweitens sind die Ökosysteme und damit auch die Anforderungen an die Zielgruppe recht unterschiedlich: TigerJython richtet sich in erster Linie an Schülerinnen und Schüler, die Python und/oder Informatik lernen wollen oder sollen, Processing.py hat dagegen eine erwachsene Zielgruppe im Blick, die kreativ programmieren möchte. Processings Ökosystem ist breiter gestreut und umfangreicher, dafür aber in einigen Fällen weniger spezialisiert.

  1. Theoretisch müßte dies aber möglich sein, GameGrid ist im Kern eine Java-Bibliothek (JGameGrid), und dort ist ein Export in ein .jar-File vorgesehen. Leider ist dies wohl bei der Portierung nach TigerJython nicht mit implementiert worden. 


(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

Diese Spalte wurde absichtlich leergelassen!


Werbung


image  image  image
image  image  image


image