Inhaltsverzeichnis

Animation von Grafikobjekten (die act-Methode)

Alle modernen Game-APIs besitzen eine Game-Loop, die fortwährend läuft und mit konstanter Frequenz (i.d.R. 60-mal pro Sekunde) eine Methode zur Berechnung des neuen Spielzustands aufruft (Update Method). Diese wiederum ruft die Update-Methode aller Spielobjekte auf, so dass auch diese ihren neuen Zustand berechnen können. Anschließend wird der Bildschirm gelöscht und alle graphischen Objekte werden neu gezeichnet (Rendering).

Auch in unserer Programmier-API gibt es diese Game-Loop. Sie wird 30-mal pro Sekunde aufgerufen und ruft ihrerseits die Update-Methode aller Spielobjekte auf, genauer: Diese Methode heißt act und ist in allen Klassen enthalten, die Unterklassen der Klasse Actor sind, insbesondere auch in allen Grafikklassen (Rectangle, Circle, …).

Wenn wir also eine Klasse schreiben, die von einer Grafikklasse (oder direct von der Klasse Actor) erbt, können wir diese act-Methode mit unserer eigenen act-Methode überschreiben, so dass dann diese 30-mal pro Sekunde aufgerufen wird.

Klingt kompliziert? Keine Angst, anhand der folgenden Beispiele lernst Du schnell, wie es geht und welche großartigen Möglichkeiten sich Dir damit eröffnen!

Beispiel 1: Drehendes Rechteck

Beispiel 2: Hin- und herbewegende Rechtecke

Beispiel 3: Fliegende Bälle

Jetzt wird's Zeit für ein anspruchsvolleres Beispiel: Wir wollen Bälle simulieren, die vom der Mitte des unteren Bildschirmrandes aus hochgeworfen werden und sich unter dem Einfluss der Gravitationskraft möglichst „natürlich“ bewegen. Dazu nutzen wir die Methode der kleinen Schritte. Sie bedeutet in unserem Fall, dass wir jede 30-tel Sekunde die neuen Werte für die Position ($x_{neu}, y_{neu}$) und die Geschwindigkeit ($v_{x, neu}, v_{y, neu}$) aus den alten Werten $x, y, vx, vy$ folgendermaßen berechnen: $$v_{x, neu} = v_x$$ $$v_{y, neu} = v_y - g\cdot\Delta t$$ $$x_{neu} = x + v_{x, neu}\cdot\Delta t$$ $$y_{neu} = y + v_{y, neu}\cdot\Delta t$$ Das $g$ in der zweiten Gleichung ist die Erdbeschleunigung $g = 9,81\frac{m}{s^2}$. Aus dem „-“ wird im Programm ein „+“, da die Y-Achse nach unten zeigt. $\Delta t$ ist in unserem Fall $\frac{1}{30} s$.

Als Spieleprogrammierer wollen wir natürlich, dass der Algorithmus möglichst schnell abläuft. Wir setzen daher $$\Delta t = 1 s$$ und passen dafür die Anfangsgeschwindigkeit und die Beschleunigung etwas an. Da sich $v_x$ nicht ändert, ist bei jedem Zeitschritt also nur noch folgendes zu tun: $$v_{y, neu} = v_y + g$$ $$x_{neu} = x + v_x$$ $$y_{neu} = y + v_{y, neu}$$ Als Physiklehrer überfällt mich ein großes Unbehagen, wenn ich an die Einheiten der drei obigen Gleichungen denke. Stellt Euch daher rechts jeweils „$\cdot 1 s$ vor, damit Ihr wieder ruhig schlafen könnt ;-) Als Programmierer freue ich mich aber über die einfache und performante Umsetzung. Die zweite und dritte Gleichung zusammengenommen lassen sich jetzt nämlich mit einer einzigen Java-Anweisung erledigen: move(vx, vy).

Erzeuger-Objekt

Im Beispiel mit den hin- und herbewegenden Rechtecken haben wir die neuen Rechtecke im Hauptprogramm erzeugt. Das ist problematisch, da bei vielen Laufenden actor-Methoden nicht sichergestellt ist, mit welcher Geschwindigkeit das Hauptprogramm durchlaufen wird. Stell Dir vor, in einem Spiel würde die Rate, mit der vom Rechner Gegner erzeugt werden, von der Geschwindigkeit Deines Rechners abhängen!
Wir wollen es diesmal besser machen und erledigen die Erzeugung der Bälle ebenfalls in einem Ereignis-Handler. Dazu erstellen wir die Klasse Erzeuger als Unterklasse von Actor. Letztere besitzt eine act-Methode, die 30-mal pro Sekunde aufgerufen wird. Wir überschreiben sie mit einer eigenen Methode, die bei jedem fünften Aufruf einen neuen Ball erzeugt.

Beispiel 4: Feuerwerk

Dieses Beispiel habe ich als Wiederholungsübung für meine zehnten Klassen im Schuljahr 2020/21 geschrieben. Damals war wegen er Corona-Epidemie das Sylvesterfeuerwerk ausgefallen.