image image


Pygame Zero objektorientiert

In meinen ersten Erkundungen zu Pygame Zero im März dieses Jahres hatte ich angemeckert, daß ich Variablen als global deklarieren mußte. Dies halte (nicht nur) ich für schlechten Programmierstil und hatte daher nach einer Lösung gesucht. Doch die gesamte, mir bekannte Literatur einschließlich der offiziellen Dokumentation (aus der ich der Idee zum Beispielprogramm hatte) steckte voller globaler Variablen und niemand schien je auf die Idee gekommen zu sein, dies zu ändern.

image

Dabei ist die Lösung recht einfach – sie heißt Objektorientierung: Denn ähnlich wie man in Pygame Unterklassen von Sprite anlegen kann, kann man natürlich auch in Pygame Zero Unterklassen der (wichtigen) Klasse Actor anlegen:

class Alien(Actor):
    
    def __init__(self, image, pos):
        Actor.__init__(self, image)
        self.pos = pos
        self.hit = False
    
    def show(self):
        if self.hit:
            screen.draw.textbox("Eek!", (100, 100, 200, 50))
        self.draw()
    
    def move(self):
        self.left += 2
        if self.left > WIDTH:
            self.right = 0
    
    def set_hurt(self):
        self.image = "alienhit"
        self.hit = True
        clock.schedule_unique(self.set_normal, 1.0)
    
    def set_normal(self):
        self.image = "alienwalk1"
        self.hit = False

Und schon ist hit keine Variable mehr, die man im Zweifelsfall als global deklarieren muß, sondern eine Eigenschaft der Klasse Alien, die an die jeweilige Instanz dieser Klasse gekoppelt ist.

Eine Besonderheit scheint man beachten zu müssen: Da die Methoden update() und draw() anscheinend global zu Pygame Zero gehören, reagiert das Programm verschnupft, wenn diese Namen irgendwo als Klassenmethoden deklariert und aufgerufen werden (daher habe ich sie in der Klasse Alien move() und show() genannt).1

Das Hauptprogramm ist, da die gesamte Funktionalität in die Klasse Alien ausgelagert wurde, erfrischend kurz:

alien = Alien("alienwalk1", (200, 250))

def update():
    alien.move()

def draw():
    screen.fill((0, 80, 125))
    alien.show()

def on_mouse_down(pos):
    if alien.collidepoint(pos):
        alien.set_hurt()

Natürlich ist das Programm bei solch einem kurzen Beispiel nur »gefühlt« kürzer. Das ursprüngliche Programm (ohne Objektorientierung) war 38 Zeilen lang, die objektorientierte Version 45 Zeilen. Die separate Klassendefinition kostet schon ein paar zusätzliche Zeilen. Aber bei einem längeren und komplexeren Programm dürfte man diese Zeilen schnell einsparen und vor allen Dingen – die globale Deklaration des Flags hit ist weggefallen. Denn diese globale Deklaration war ja das, was mich gestört hatte.

image image

Und nun noch den vollständigen Programmtext zum Nachvollziehen und Nachprogrammieren. Die beiden Bilder des Aliens entstammen übrigens wieder der wunderbaren, freien (CC0 1.0 Universal) Sammlung von Kenney.nl.

import pgzrun

class Alien(Actor):
    
    def __init__(self, image, pos):
        Actor.__init__(self, image)
        self.pos = pos
        self.hit = False
    
    def show(self):
        if self.hit:
            screen.draw.textbox("Eek!", (100, 100, 200, 50))
        self.draw()
    
    def move(self):
        self.left += 2
        if self.left > WIDTH:
            self.right = 0
    
    def set_hurt(self):
        self.image = "alienhit"
        self.hit = True
        clock.schedule_unique(self.set_normal, 1.0)
    
    def set_normal(self):
        self.image = "alienwalk1"
        self.hit = False
        

WIDTH = 400
HEIGHT = 400
TITLE = "Älien OOP"

alien = Alien("alienwalk1", (200, 250))

def update():
    alien.move()

def draw():
    screen.fill((0, 80, 125))
    alien.show()

def on_mouse_down(pos):
    if alien.collidepoint(pos):
        alien.set_hurt()


pgzrun.go()

Ich gewinne mehr und mehr den Eindruck, daß Pygame Zero für die Spieleentwicklung daß sein könnte, was Processing für Designer und Gestalter ist – ein einfaches Werkzeug, um schnell Ideen zu testen und zu realisieren. Ich bin erst einmal beeindruckt und werde mich daher weiter damit beschäftigen. Still digging!

image

  1. Das ist zumindest meine Vermutung. In der Dokumentation hatte ich nichts dazu gefunden, aber als die Methode move() noch update() und die Methode show() noch draw() bei mir hießen, kam das Programm mit einer Fehlermeldung hoch. 


(Kommentieren) 

image image



Über …

Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter, 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