Schleifen und Bedingungen
if-Statements
im Deutschen auch als Bedingungen und Verzweigungen bezeichnet
Mit der if-Bedingung können bestimmte Programmteile selektiv ausgeführt werden. Die if-Anweisung von Processing funktioniert wie die if-Anweisung anderer Programmiersprachen. Die Syntax ist beispielsweise identisch mit der der if-Anweisungen von Java, C und C++. Ihre einfach allgemeine Form sieht wie folgt aus:
if(Bedingung) Anweisung;
Die Bedingung ist ein Bool’scher Ausdruck. Ist die Bedingung wahr, dann wird die Anweisung ausgeführt, andernfalls wird sie übergangen. Ein Beispiel:
if(10 < 11) println("10 ist kleiner als 11");
Da 10 kleiner als 11 ist, ist die Beingung wahr und println() wird ausgeführt.
In folgenden Beispiel ist die Situation anders:
if(10 < 9) println("Dies wird nicht angezeigt");
Boole’sche Operatoren
Ein Operator ist ein Symbol, das den Compiler auffordert, eine bestimmte mathematische oder logische Operation durchzuführen.
Operator | Bedeutung |
---|---|
< | kleiner als |
<= | kleiner als oder gleich |
> | größer als |
>= | größer als oder gleich |
== | gleich |
!= | ungleich |
&& | und |
| | | oder |
Bitte beachte: Die Überprüfung auf Gleichheit wird mit doppelten Gleichheitszeichen durchgeführt, da es sich sonst um eine Zuweisung handeln würde!
Verschachtelte If-Anweisung
Die vollständige Form der if-Anweisung lautet:
if(Bedingung) { Anweisung; } else { Anweisung; }
Die Ziele von if und else sind einzelne Anweisungen oder Anweisungsblöcke. Die else-Klausel ist optional.
Hat die Bedingung des Ausdrucks den Wert true, dann wird der Anweisungsblock von if ausgeführt, andernfalls wird, falls vorhanden, der Anweisungsblock von else ausgeführt. Beide werden niemals gleichzeitig ausgeführt. Als verschachtelte if-Bedingung wird sie dann bezeichnet, wenn nach dem else gleich wieder ein if kommt.
if(Bedingung) { Anweisung; } else if(Bedingung) { Anweisung; } else { Anweisung; }
Loop
werden auch als Schleifen bezeichnet
Mit einer Schleife kann Programmcode wiederholt ausgeführt werden. Processing verfügt über ein leistungsfähgies Sortiment von Schleifenkonstrukten. An dieser Stelle wird die for-Schleife erörtert.
Allgemeine Form:
for(Initialisierung; Bedingung; Iteration) { Anweisung; }
In der allgemeinen Form wird bei der Initialisierung der Schleife eine Steuervariable auf ihren Anfagnswert gesetzt. Die Bedingung ist ein Boole’scher Ausdruck, der die Steuervariable testet. Liefert das Ergebnis des Tests den Wert true, wird die for-Schleife weiter durchlaufen. Hat das Ergebnis den Wert false, wird sie beendet. Der Iterationsausdruck legt fest, wie die Kontrollvariable bei jedem Schleifendurchlauf verändert wird.
count = count + 1;
Ein Profi wird den Iterationsteil allerdings nie so schreiben. Der Grund dafür ist der spezielle Inkrementoperator von Processing (Java), der diese Operation effizienter durchführt. Der Inkrementoperator ++ (zwei Pluszeichen hintereinander) vergrößert den Operanden um eins.
Schreibweise: count++;
Codeblöcke
Ein weiteres Grundelement ist der Codeblock. Ein Codeblock ist eine Gruppe von zwei oder mehr Anweisungen. Diese Anweisungen werden in eine öffnende und eine schließende geschweifte Klammer eingeschlossen. Wurde ein Codeblock einmal erstellt, dann wird er zu einer logischen Einheit, die überall dort eingesetzt werden kann, wo auch eine einzelne Anweisung verwendet werden kann.
if(w < h){ <------Blockanfang v = w * h; w = 0; } <------Blockende
Wenn w kleiner als h ist, werden beide Anweisungen innerhalb des Blocks ausgeführt. Die beiden Anweisungen innerhalb des Blocks bilden also eine logischen Einheit und eine Anweisung kann nur in Verbindung mit der anderen Anweisung ausgeführt werden. Wann immer man zwei oder mehrere Aweisungen logisch verknüpfen möchte, indem man einen Block einrichtet.
Semikolons und Einrückungen
In Processing beendet ein Semikolon eine Anweisung. Jede einzelne Anweisung muss mit einem Semikolon geschlossen werden. Es zeigt das Ende einer logischen Einheit an.
Ein Codeblock wird nicht mit einem Semikolon abgeschlossen, da dieser aus einer Reihe von Anweisungen besteht.
Processing, sowie Java, ist eine formlose Programmiersprache, bei der es keine Rolle spielt, wie Anweisungen im Verhältnis zueinander in den Zeilen angeordnet werden. Im Laufe der Jahre hat sich jedoch ein allgemeiner akzeptierter Stil für Einrückungen etabliert, der die Programme gut lesbar macht. Bei diesem Stil wird nach jeder öffnenden Klammer um einen Schritt eingerückt und nach jeder schließenden Klammer die Einrückung wieder um einen Schritt zurückgenommen.
(in diesem Kapitel wurden weite Teile aus Schildt 2004, p 43-50 zitiert)
Übungen
Übung: Wandernder Punkt
Erzeuge ein 600×600 Pixel großes Ausgabefenster und kreiere einen Punkt (Radius 10px) in der Mitte des Ausgabefensters. Dieser Punkt soll von der Mitte weg nach links wandern und nachdem er das Ausgabefenster „verlassen“ hat, wieder links in das Ausgabefenster eintreten. Benutze Variablen.
- Lösung
int x = 0; int y = 0; int radius = 10; void setup(){ background(0); size(600, 600); x = width/2; y = height/2; } void draw(){ background(0); fill(255, 14, 81); if(x >= width){ //sobald x größer als die Breite des Fensters ist, x = 0; //wird x auf 0 gesetzt } ellipse(x, y, 10, 10); x++; }
Übung: Linie folgt Mousecursor
Erzeuge ein 600×600 Pixel großes Ausgabefenster und kreiere einen Punkt (Radius 10px) der in der linken oberen Ecke platziert ist. Er soll sich langsam immer in Richtung Mousecursor bewegen und dabei eine Linie erzeugen.
- Lösung
int radius = 10; float x=0; float y=0; void setup() { background(255); size(640,360); } void draw() { //background(255); fill(0); if(mouseX <= x){ x -= 0.5; } else x += 0.5; if(mouseY <= y){ y -= 0.5; } else y += 0.5; ellipse(x, y, 10, 10); }
Es sollen 10 schwarze Kreise auf weißem Hintergrund gezeichnet werden. Jeder soll um 20px größer als der vorherige sein. Der Mittelpunkt ist dabei der Mittelpunkt des Canvas (arbeite mit relativen Werten).
Nun sollen erneut 10 schwarze Kreise gezeichnet werden, ebenfalls mit 20 px. Der Mittelpunkt soll immer die Position der Maus sein.
- Lösung
void setup(){ size(800,800); //setzt die Größe des Canvas background(255, 255, 255); //setzt die Hintergrundfarbe noFill(); //setzt die Farbe des nächsten Grafikbefehls } void draw(){ background(255, 255, 255); //setzt die Hintergrundfarbe (um den Canvas quasi zu löschen) for(int i = 0; i<100; i++){ int radius = i * 20; ellipse(width/2, height/2, radius, radius); } for(int i = 0; i<100; i++){ int radius = i * 20; ellipse(mouseX, mouseY, radius, radius); } }
Übung: Stern
Es soll zunächst ein Ausgabefenster mit einer Größe von 800x800 Pixel erzeugt werden. Alle 100 Pixel soll eine Line wegführen, das Ende der Linie befindet sich dort, wo der Mauszeiger positioniert ist.
- Lösung
void setup(){ size(800, 800); background(0); } void draw(){ background(0); stroke(255); for(int i = 0; i <= width; i+=100){ for(int j = 0; j <= height; j+=100){ line(i, j, mouseX, mouseY); } } }
Übung: Kreis mit einem Helligkeitsverlauf
Erzeuge ein 200x200 großes Ausgabefenster.
Zeichne dazu 255 Kreise, deren Füllwert sich bei jedem Kreis verändert.
(inspiriert von Greenberg 2007, p 88)
- Lösung
void setup(){ size(200,200); background(0); } void draw(){ for (int i = 255; i > 0; i--){ noStroke(); fill(255-i); ellipse(width/2, height/2, i, i); } }
Was muss nun verändert werden, wenn wir beobachten wollen, wie sich das Bild aufbaut?
- Lösung
Beachte: Lösche alle zum Loop gehörenden Klammern und ergänze fehlende Semikolons!
int i = 255; void setup(){ size(200,200); background(0); } void draw(){ noStroke(); fill(255-i); ellipse(width/2, height/2, i, i); i--; }
Übung: Bouncing Ball
Erzeuge ein 500x500 px großes Ausgabefenster und erzeuge einen sich bewegenden Ball, der von den Seiten abprallt.
- Lösung
int ballSize = 50; float xspeed = 0.0; float yspeed= 0; float xpos = 0; float ypos = 0; void setup(){ size(500, 500); background(0); noStroke(); fill(255, 14, 81); frameRate(30); xspeed= random(1, 10); yspeed= random(1, 10); xpos = random(1, width); ypos= random(1, height); } void draw(){ background(0); xpos += xspeed; ypos += yspeed; //check the borders if (xpos + ballSize/2>=width || xpos <= ballSize/2){ xspeed *= -1; } if (ypos + ballSize/2 >= height || ypos <= ballSize/2){ yspeed *= -1; } ellipse(xpos, ypos, ballSize, ballSize); }