In diesem ersten Tutorial werden wir uns wieder in die Programmierung mit Processing einarbeiten. Dazu werden wir drei Beispiele betrachten, welche uns Schritt für Schritt an die Programmierung mit Hilfe von Vektoren und Klassen heranführen.
Um den Einstieg in Processing zu schaffen schauen wir uns zunächst ein einfaches kleines Beispiel an. In diesem Beispiel sehen wir die uns vertraute Umgebung, sowie die grundlegende Programmstruktur von Processing:
void setup() // wird einmal aufgerufen void draw() // wird permanent ausgeführt
Wenn wir das Beispiel laufen lassen, sehen wir einen Ball, welcher sich innerhalb der mit size(width, height)
festgelegten Grenzen bewegt. In der draw()
Routine sind dafür drei wesentliche Schritte nötig:
Die Position wurde zu Beginn mit den Variablen float x=100
und float y=100
festgelegt. Bei jedem Aufruf von draw()
wird diese Position neu bestimmt, indem zur Ausgangsposition eine Geschwindigkeit hinzu addiert wird. Die Koordinaten der neuen Position lassen sich also mit x+=xspeed
bzw. y+=yspeed berechnen
.
Die Kollision mit den Kanten muss für jede der vier Kanten separat durchgeführt werden. Dazu benötigen wir sowohl die Position des Balls (x,y) und natürlich dessen Radius. Den Radius können wir berechnen indem wir die ursprünglich festgelegte Grösse float size = 50
durch 2 teilen. Also ergibt sich size/2
. Diesen Radius testen wir dann zusammen mit der aktuellen Position auf Kollision mit den Rändern und kehren die Geschwindigkeit um z.B. xspeed *-1
. Somit bewegt sich der Ball in der nächsten Itteration in die entgegengesetzte Richtung.
Links: x < 0 + size / 2
Rechts: x > width - size / 2
Oben: y < 0 + size / 2
Unten: y > height - size / 2
Zuletzt legen wir fest, wie unser Ball dargestellt werden soll. Dazu geben wir ihm eine Farbe für die Umrandung stroke(0)
, legen fest, wie dick diese sein soll strokeWeight(2)
und legen eine Füllfarbe fest fill(127)
. Danach zeichnen wir eine Ellipse an der Position, welche wir vorher berechnet haben ellipse(x,y,size,size)
.
Das obige Beispiel lässt sich mit Hilfe von Vektoren vereinfachen. Vektoren erlauben uns die Position und die Geschwindigkeit anders zu schreiben:
float x; float y; float xspeed; float yspeed;
wird zu:
PVector location; PVector velocity;
Vektoren erlauben es uns also zwei Werte in einer Variablen zu speichern – bewegen wir uns im 3D Raum können auch drei Werte gespeichert werden. Vektoren sind also die Bezeichnung für eine Differenz zwischen sei Punkten in einem Raum.
Ein Vektor gibt uns also an, wie wir von einem Punkt zum nächsten gelangen. Zum Beispiel: Gehe in x-Richtung 10 Schritte und in y-Richtung -10 Schritte…
Wenn wir dies nun auf unser Beispiel anwenden, dann müssen wir folgende Änderungen vornehmen:
Dazu deklarieren wir die Variablen PVector location
und PVector velocity
. Im setup()
initialisieren wir dann die zuvor festgelegten Variablen und weisen ihnen Startwerte zu:
location = new PVector(100,100); velocity = new PVector(2,2);
Wie im ersten Beispiel müssen wir auch jetzt die neue Position anhand der letzten Position location
und der Geschwindigkeit velocity
berechnen. Dazu hilft es zu wissen, dass sich Vektoren sehr einfach miteinander addieren und subtrahieren lassen. Dies geschieht immer Komponentenweise, also separat für x-Werte und y-Werte
Um den Vektor w zu berechnen, welcher durch Addition von u und v zu erhalten ist, gilt folgendes Vorgehen:w = u + v
Auflösung nach Komponenten:wx = ux + vx
wy = uy + vy
In unserem Beispiel also:wx = 10 + 4 = 14
wy = -10 + 6 = -4
Um Objekte der Klasse PVector zu addieren verwenden wir in Processing den Begriff .add()
. Wenden wir also dieses Wissen auf unser BouncingBall Beispiel an, so ändert sich:x = x + xspeed;
y = y + yspeed;
Zu:location.add(velocity);
Dieser Schritt ist nach wie vor nötig und wird lediglich in der Schreibweise für Vektoren angepasst. Dabei gilt zu beachten, dass die einzelnen Komponenten eines Vektors, also die x und x Werte mit einer Punktnotation erhalten werden können. Den x-Wert unserer Position erhält man folglich durch location.x
und den y-Wert durch location.y
.
Die Darstellung bleibt auch gleich, bis auf die Schreibweise. Leider ist es nicht möglich ellipse(x,y,size,size)
mit ellipse(location,size,size)
zu ersetzen. Stattdessen schreiben wir wieder komponentenweise ellipse(location.x,location.y,size,size)
.