Spielfiguren mit Eigenleben

Das funktioniert so alles wunderbar. Aber sobald wir mehrere Spielfigur-Objekte haben, die sich allesamt auf dem Spielfeld tummeln, müsste unser Hauptprogramm nacheinander jede Spielfigur mit ihren Positionen abfragen und sie entsprechend bewegen. Wenn das Spiel dann umfangreicher wird, kommt noch viel mehr hinzu, und schon ist die Gefahr, dass man den Überblick verliert, wieder sehr groß, und das Hauptprogramm wird sehr lang und kompliziert.

Nun ist aber gerade das Großartige an der objektorientierten Programmierung, dass unsere Objekte völlig eigenständig sein können. Wenn der Fisch sich sowieso immer nur nach rechts bewegen soll und dann wieder von links anfängt, dann gehört diese Bewegung als »seine Bewegungsmethode« zum Fisch dazu – und muss nicht von außen in einem separaten Programm gesteuert werden.

Objekte können bekanntlich Eigenschaften und Fähigkeiten haben. Wie wäre es, wenn wir dem Fisch als Fähigkeit das Schwimmen in einer eigenen Methode mitgeben?

Dazu müssen wir am Anfang des Programms eine eigene Fisch-Klasse erzeugen, die von der Klasse Actor abgeleitet ist und der wir eine eigene Fähigkeit mitgeben, das Schwimmen.

class Fisch(Actor):
def schwimmen(self):
self.move(1)
if self.getX() > 630:
self.setX(-30)

Wir haben also eine neue Objektklasse mit dem Namen Fisch definiert, die von Actor abgeleitet ist, also alles kann, was Actor kann. Zusätzlich bekommt sie aber jetzt auch noch die Methode schwimmen().

Das Fischobjekt wird jetzt so erstellt und auf das Spielfeld gebracht:

fisch = Fisch("sprites/babelfish.gif")

feld.addActor(fisch,Location(200,200))

Und die Schleife im Hauptprogramm wird viel einfacher:

repeat:
fisch.schwimmen()
feld.refresh()
delay(20)

Wenn wir jetzt einen zweiten Fisch hinzufügen wollen, dann ist es noch deutlicher. Erzeugt und aufs Spielfeld gebracht wird er so:

fisch2 = Fisch("sprites/babelfish.gif")
feld.addActor(fisch2,Location(200,200))

Und die Hauptschleife bekommt nur einen zusätzlichen Befehl:

repeat:
fisch.schwimmen()
fisch2.schwimmen()
feld.refresh()
delay(20)

Das gesamte Programm sieht dann zum Beispiel so aus:

from gamegrid import *
feld = GameGrid(600,600,1,None,"sprites/reef.gif",False)
feld.setTitle("Korallenriff")
class Fisch(Actor):
def schwimmen(self):
self.move(1)
if self.getX() > 630:
self.setX(-30)

fisch = Fisch("sprites/babelfish.gif")
feld.addActor(fisch,Location(200,200))
fisch2 = Fisch("sprites/babelfish.gif")
feld.addActor(fisch2,Location(300,300))
feld.show()
repeat:
fisch.schwimmen()
fisch2.schwimmen()
feld.refresh()
delay(20)

Auf die Weise tummeln sich zwei Fische im Wasser, beide schwimmen nach rechts und beginnen dann wieder links, aber die Bewegung musste nur einmal in der Fisch-Klasse definiert werden und ist auf jedes neue Objekt anwendbar, das mit dieser Klasse erzeugt wurde.

Aber es geht sogar noch einfacher und besser mit unserem gamegrid.