Schlagwort-Archiv: operatoren

processing

Processing – Fallbedingungen (If-Then-Else) und Zufallszahlen

Hallo,

endlich weißt du was Variablen sind (Behälter, in denen beliebig Werte abgelegt oder herausgenommen werden können), und damit bist du schon ein ganzes Stück weiter. Heute möchte Ich dir zeigen, wie man mit Fallbedingungen arbeitet. Aber .. Was sind Fallbedingungen?

Fallbedingungen

Mit sog. Fallbedingungen kannst du den Programmablauf ändern, das heißt bei bestimmten eintretenden oder nicht eintretenden Ereignissen, passiert dies und das. Beispiel: Wenn die X-Mausposition kleiner oder gleich 100, mache schwarzen Hintergrund, ansonsten mache weißen Hintergrund. So in etwa. Es ist immer dieses Wenn … Dann …
Und wie das ganze Programmiertechnisch aussieht, dazu kommen wir jetzt.
“Wenn” übersetzt ins Englische bedeutet “if”. Da das eine Befehlsanweisung ist, musst du hier wieder Anfang und Ende des Anweisungsblock durch geschweifte Klammern definieren. Wir fragen im Code etwa so ab:

WENN(Dies passiert)
{
//Dann führe diesen Code aus
}

also quasi:

if(Bedingung erfüllt)
{
//Führe diesen Code aus
}

Im letzten Artikel hab’ Ich dir zudem Vergleichsoperatoren gezeigt, wie schon angesprochen, kommen die bei den Fallbedingungen zum Einsatz.
Doch halt, natürlich können wir mit so einem Wenn-Dann nicht nur Zahlen und Rechnungen abfragen. Was so eine Anweisung wirklich erwartet, ist der boolesche Wert true.
Ein boolscher Wert kann genau 2 Zustände annehmen, nämlich true oder false, also Wahr oder Falsch.
Dafürt gibt es den Datentyp boolean(ausgesprochen etwa “buhlien”).
Beispiel: 5 kleiner 7 -> trifft zu, 5 ist in der Tat kleiner als 7, der Vergleich ergibt also true.
So ist es immer und überall, und das nicht nur bei Rechenoperationen, sondern zum Beispiel auch beim Vergleich zweier Texte oder sonst etwas.
Aber sehen wir uns doch jetzt endlich mal den Code an für ein einfaches Beispiel, nämlich das von vorhin.
Ich möchte folgendes: Wenn die X-Position der Maus größer oder gleich der Hälfte der Breite des Fensters entspricht, möchte Ich einen weißen Hintergrund, andernfalls einen schwarzen Hintergrund.
Wo schreiben wir den Code? Hierbei ist eigentilch egal, ob wir ihn in draw() setzen oder ins mouseMoved()-Event, denn draw() wird ständig ausgeführt, mouseMoved() immer dann, sobald(solang) die Maus bewegt wird. Aber schau es dir an:

Sourcecode
void setup()
{
  size(300, 300);
  smooth();
  background(255);
}

void draw()
{
  
}

void mouseMoved()
{
  background(255);
  if(mouseX >= width / 2)
  {
    background(0);
  }
}

Gar nicht schwer, oder? Du siehst, die Hintergrundfarbe wird, egal wo die Maus ist, am Anfang immer auf Weiß gesetzt. Ist die Maus über der Hälfte der Breite des Fensters, wird der Hintergrund nachträglich auf Schwarz gesetzt.
Es ist einfach, du schreibst die Abfrage(if), stellst die Bedingung (in Klammern, bei unserem Beispiel wird abgefragt ob mouseX >= Hälfte der Breite des Fensters) und führst bei true den Code aus.
Ah, da hab’ Ich was für dich, um dir das mit der Bedingung klar zu machen, sieh mal:

Sourcecode
void setup()
{
  size(300, 300);
  smooth();
  background(255);
}

void draw()
{
  
}

void mouseMoved()
{
  background(255);
  if(mouseX >= width / 2)
  {
    background(0);
  }
  println(mouseX >= width / 2);
}

Fällt dir was auf? Schau unten in der IDE im schwarzen Fenster nach ;-)
Du weißt nun, ist eine Bedingung erfüllt, wird Code ausgeführt. Doch was, wenn die Bedingung false ergibt? Dafür gibt es auch was: WENN [...] DANN [...] ANDERNFALLS [...]. Ins englische übersetzt als else.
Wenn Taste Q gedrückt wird, schreibe einen Text, wenn nicht, schreibe anderen Text. Beispiel:

Sourcecode
void setup()
{
  size(300, 300);
  smooth();
  background(255);
}

void draw()
{
  
}

void keyPressed()
{
  background(255);
  fill(0);
  if(key == 'q')
  {
    text("Juhu, Q wurde gedrückt", 100, 100);
  }
  else
  {
    text("Es wurde nicht " + key + " gedrückt", 100, 100);
  }
}

Soweit nicht soo schwer, oder? Und wenn wir nun noch mit Variablen arbeiten, können wir auch schon ein paar tolle Ergebnisse erzielen. Stell dir vor du willst eine einfache Linie zeichnen, die sich vertikal von links nach rechts bewegt. Hat die Linie den Rand erreicht, soll sie wieder bei 0 starten:

Sourcecode
void setup()
{
  size(300, 100);
  smooth();
  background(255);
  //Zu Anfangs den Wert von x setzen
  x = 0;
}

int x;

void draw()
{
  //Hintergrund Weiß
  background(255);
  //Zeichenfarbe Schwarz
  stroke(0, 230);
  //Strichdicke 3Pixel
  strokeWeight(3);
  //Linie (in X-Richtung den Wert vin Variable X)
  line(x, 0, x, height);
  //X um +1 erhöhen
  x++;
  //Wenn x größer oder gleich Breite des Fensters,
  //setze x auf Null
  if(x >= width){x = 0;}
  //Füllen mit Schwarz (Rechteck)
  fill(0);
  //Rechteck zeichnen
  rect(5, 0, 50, 12);
  //Mit weiß füllen (für die Schrift)
  fill(255);
  //Text ausgeben (welchen Wert hat x)
  text("x = " + x, 10, 10);
}

Cool nicht wahr :-)
Und damit nicht genug, denn es ist auch möglich, auf mehrere zu prüfen. Beispiel:
WENN Mausposition X kleiner als 100 UND Mausposition Y kleiner als 100, mache Hintergrund auf Schwarz, ANDERNFALLS mache Hintergrund auf Weiß. Das Beispiel versuchen wir einmal, zuvor aber noch etwas zu …

Logische Operatoren

Logische Operatoren wären UND, ODER und NICHT. Das Zeichen für UND ist hierbei &&. Das Zeichen für ODER ist ||. Um einen Ausdruck oder eine Bedingung zu negieren, setzt du einfach ein Ausrufezeichen (!) davor.
Doch schau dir den Code an:

Sourcecode
void setup()
{
  size(300, 300);
  smooth();
  background(255);
}

void draw()
{
}

void mouseMoved()
{
  //Wenn MausX kleiner oder gleich 100 UND
  //MausY kleiner oder gleich 100, DANN ..
  if (mouseX <= 100 && mouseY <= 100)
  {
    background(0);
    fill(255, 0, 0);
  }
  else
  {
    background(255);
    noFill();
  }
  //Damit man auch sieht, wo 100 und 100 ist,
  //zeiche Ich ein Rechteck:
  stroke(0);
  rect(0, 0, 100, 100);
}

Gar nicht so schwer, stimmt’s? Wollen wir uns zuletzt noch ein Praxisbeispiel ansehen. Danach zeige Ich dir noch Zufallszahlen. Aber nun zum praktischen Beispiel. Nehmen wir eine Ellipse. Wenn Taste “a” gedrückt wird, soll diese horizontal von links nach rechts fliegen, jeweils an den Wänden abprallen und zurückfliegen. Drückst du “+”, bzw. “-” soll so die Geschwindigkeit reguliert werden. Drücke die Taste “0″, um die “Kugel” an den Anfangspunkt zu setzen. Befindet sich die Maus im Bereich der Ellipse, kannst du die Kugel herumziehen, lässt du die Maus los, fliegt sie weiter. Aber schau selbst:

Sourcecode
void setup()
{
  size(300, 300);
  smooth();
  background(255);
  x = 50;
  y = height / 2;
  ballSize = 50;
  speed = 2.0;
  richtungX = 1;
  richtungY = 1;
  lock = false;
  drag = false;
}

//X- und Y-Koordinaten des Balles und die Größes festlegen,
//außerdem die Richtung in die er sich bewegt
int x, y, ballSize, richtungX, richtungY;
//Geschwindigkeit
float speed;
//Variablen um anzugeben, ob der Ball herumgezogen wird
boolean lock, drag;

void draw()
{
  background(255);
  noStroke();
  fill(0);
  //Ellipse wird gezeichnet
  ellipse(x, y, ballSize, ballSize);
  //wenn der Ball nicht gezogen wird, soll er
  //von allein weiterwandern
  if(lock == false){x += speed * richtungX;}
  //Wenn der Ball an der Wand abprallt, richtung ändern
  if(x >= width - ballSize / 2 || x <= ballSize / 2)
  {
    //Einfaches Prinzip wie damals in der Schule, 
    //Zahl mal -1 ändert jeweils das Vorzeichen, also
    //aus Plus wird Minus, aus Minus wird Plus
    richtungX *= -1;
  }
}

void keyPressed()
{
  //Wenn + gedrückt wird, erhöhe speed
  if(key == '+' && speed <= 7.0)
  {
    speed += 0.5;
  }
  if(key == '-' && speed >= 0.5)
  {
    //Wenn - gedrückt wird, verringere speed
    speed -= 0.5;
  }
  if(key == '0')
  {
    //Wenn Null (0) gedrückt wird, setze Ellipse auf
    //Startposition zurück
    x = 27;
    y = height / 2;
  }
}

void mouseDragged()
{
  //Wenn sich Maus innerhalb des Balles befindet, dann...
  if(mouseX <= x + ballSize / 2 && mouseX >= x - ballSize / 2 &&
     mouseY >= y - ballSize / 2 && mouseY <= y + ballSize / 2)
  {
    //.. setze Variable drag auf true.
    drag = true;
  }
  //Wenn drag true ergibt, dann..
  if(drag)
  {
    //..sperre automatische Bewegung der Kugel und..
    lock = true;
    //..setze Werte von x und y auf Mausposition
    y = mouseY;
    x = mouseX;
  }
}

void mouseReleased()
{
  //Wird die Maus losgelassen, ist der verschiebevorgang beendet,
  //und die Kugel fliegt allein weiterhin von links nach rechts, 
  //bzw von rechts nach links, je nachdem.
  lock = false;
  drag = false;
}

Cool oder =D
Eigentlich alles gar nicht soo schwer, gute Mathematikkenntnisse schaden nie, und bei Processing ist das sogar beste Voraussetzung, um bessere Ergebnisse zu erzielen. Bevor Ich diesen Artikel abschließe, möchte Ich dir noch Zufallszahlen zeigen. Zufall übersetzt heißt random. Und damit kannst du Zufallszahlen generieren. Random ist immer vom Datentyp float, also Kommazahl.
Müssen wir Werte übergeben? Aber ja. Insgesamt zwei, nämlich einen Minimalwert und einen exklusiven Maximalwert, zwischen dem eine zufällige Zahl generiert werden soll. Das heißt du möchtest eine zufällige Zahl, diese soll aber auf jeden Fall zwischen 10 und zwanzig liegen? Dann schau her, der schlichte Befehle dafür lautet

random(minimum, maximum);

Und um dazu gleich ein Beispiel zu geben:

Sourcecode
void setup()
{
  size(200, 200);
  smooth();
  background(255);
}

void draw()
{
  
}

void mouseClicked()
{
  float zufall = random(10, 20);
  background(255);
  fill(0);
  textSize(15);
  text(zufall, 100, 100);
}

Du brauchst nichts weiter tun, als mit der Maus zu klicken, es wird dann immer eine neue Zufallszahl generiert und ausgegeben. Wenn die Zahl von Null bis irgendwas generiert werden soll, kannst du dir einen Parameter sparen, dann wird die Zahl immer von Null bis zum Maximum generiert, Höchstwert immer exklusive, das bedeutet der Höchstwert wird nie generiert werden. 20 exklusive bedeutet demnach zwischen 0.000 und 19.999. Ich denke aber, du willst lieber eine gerade Zahl haben, also ohne Kommastellen, nicht wahr? Du “konvertierst” den Wert einfach in int. Ich zeige dir mal was Ich meine:

Sourcecode
void setup()
{
  size(200, 200);
  smooth();
  background(255);
}

void draw()
{
}

void mouseClicked()
{
  int zufall = int(random(10000));
  background(255);
  fill(0);
  textSize(30);
  text(zufall, width / 2 - 25, height / 2);
}

Ich denke das ist soweit klar, wird Zeit dass wir damit auch was anfangen können. Mal folgender Code, dort wird nun jeweils ein Rechteck zufälliger Größe über das andere gezeichnet, an zufälligen Stellen und mit zufälliger Füllfarbe:

Sourcecode
void setup()
{
  size(200, 200);
  smooth();
  background(0);
}

void draw()
{
  noStroke();
  int rndColorR, rndColorG, rndColorB, rndX, rndY;
  rndColorR = int(random(255));
  rndColorG = int(random(255));
  rndColorB = int(random(255));
  rndX = int(random(25, 150));
  rndY = int(random(25, 150));
  stroke(rndColorB, rndColorB, rndColorR);
  fill(rndColorR, rndColorG, rndColorB);
  rect(random(-50, width), random(-50, height), rndX, rndY);
}

Willst du das Bild nun auch noch speichern, gibt es dafür einen wirklich sehr simplen einfachen Befehl. Schreibe nur save und übergib den Namen für das Bild. Sehen wir uns den Code doch einmal an:

Sourcecode
void setup()
{
  size(200, 200);
  smooth();
  background(0);
}

void draw()
{
  noStroke();
  int rndColorR, rndColorG, rndColorB, rndX, rndY;
  rndColorR = int(random(255));
  rndColorG = int(random(255));
  rndColorB = int(random(255));
  rndX = int(random(25, 150));
  rndY = int(random(25, 150));
  stroke(rndColorB, rndColorB, rndColorR);
  fill(rndColorR, rndColorG, rndColorB);
  rect(random(-50, width), random(-50, height), rndX, rndY);
}

int zaehler = 0;
void mousePressed()
{
  noLoop();
  save("Zufall-" + zaehler + ".png");
  zaehler++;
}

void mouseReleased()
{
  loop();
}

Wird die Maus gedrückt, wird die Variable zaehler um 1 erhöht, der Durchlauf(draw()) unterbrochen, das Bild gespeichert. Wird die Maus losgelassen, läuft draw() weiter. Ja, da sind 2 Befehle die du noch nicht kanntest, nämlich noLoop() um die Ausführung von draw() zu unterbrechen, und loop() um die Ausführung fortzusetzen.
Die Bilder werden dann im Verzeichnis, in dem das Projekt liegt, gespeichert.

Folgendes Beispiel zeigt, wie Punkte zufälliger größe und zufälligen Graustufen an zufällige Positionen des Fensters gezeichnet werden. Klickedie rechte Maustaste, um das Fenster zu leeren:

[expand title=">> Code ausklappen<<"]

Sourcecode
void setup()
{
  size(300, 300);
  smooth();
  background(0);
}

void draw()
{
  strokeWeight(random(7));
  stroke(random(255));
  point(random(width), random(height));
}

void mouseClicked()
{
  if(mouseButton == RIGHT){background(0);}
}

[/expand]

Sieht doch für das bisschen Code gar nicht mal schlecht aus, nicht wahr :-)
Wie Ich versprochen habe, brauchst du nicht viel Code, um interessante Effekte zu zaubern, du musst lediglich die gegebenen Befehle an den richtigen Stellen einzusetzen wissen. Ein letztes Beispiel möchte Ich dir noch zeigen:
Es wird von rechts nach links jeweils eine Linie gezeichnet, eine vertikale Linie. Dabei soll sie jeweils eine zufällige Länge(in dem Fall Höhe) haben. Sind die Linien bei kleiner Null angelangt, geht’s von vorne los. Du hast einen weißen Hintergrund und schwarze Linien, damit der Effekt noch besser rüberkommt, zeichne Ich vor der schwarzen immer noch eine weiße Linie, das wird erst beim zweiten Durchlauf sichtbar, aber das siehst du gleich. Schau her, kopier den Code und führe Ihn bei dir aus:

Sourcecode
void setup()
{
  size(300, 300);
  smooth();
  background(255);
  x = width + dicke;
  dicke = 7;
  //frameRate legt fest, wieviele Frames pro sekunde 
  //gezeigt werden. Standardwert ist 60
  frameRate(32);
}

int x, dicke;
void draw()
{
  //Endpunkte von Linien Eckig
  strokeCap(SQUARE);
  //Strichdicke festlegen
  strokeWeight(dicke);
  //Strichfarbe Weiß
  stroke(255);
  //Linie um beim nächsten durchlauf das "übermalen" zu simulieren
  line(x - dicke, 0, x - dicke, height);
  //Strichfarbe Schwarz
  stroke(0);
  //Linie die sich von rechts nach links bewegt, und
  //dabei vertikal eine zufällige Länge hat
  line(x, height - 50, x, height - 50 - int(random(1, height - 60)));
  //Variable x verringern, damit sich die Linien
  //nach links bewegen
  x -= dicke;
  //Wenn die Linie bei kleiner 0 angekommen ist...
  if(x < 0 - dicke * 2)
  {
    //..dann fang von vorne an
    x = width + dicke;
  }
}

Und wenn du anstatt stroke(0); nun stroke(random(255)); schreibst, hast du sogar zufällige Graustufen. Oder gar stroke(random(255), random(255), random(255)); für völlig Bunte Linien :-)
Ändere auch in void setup() einmal den initialwert für die Variable “dicke” um dir das mal anzusehen, spiele auch mit der frameRate herum. Auch sieht es interessant aus, wenn du frameRate auf 60 setzt, stroke weiter auf Null lässt und dicke auf 1 stellst, dann bekommst du so etwas:


Originalgröße

Probiere mit random und den Fallbedingungen ein wenig herum, und schau, was alles möglich ist. Es ist wirklich einfach. Tausche Codezeilen um herauszufinden, welchen Effekte diese Umstellung ergibt. Gestalte es dynamischer oder mach beim Beispiel von eben die länge der Linien abhängig vom Größenunterschied zwischen mouseX und pmouseY, und und und… Alles ist möglich, du kannst nichts kaputtmachen, lerne die gegebenen Befehle an den richtigen Stellen einzusetzen, um noch bessere Animationen und Bilder zu machen..

Für diesen Teil, also was Fallbedingungen (Wenn – Dann – Ansonsten ..) und Zufallszahlen angeht, bin Ich hiermit fertig. Im nächsten Artikel zeige Ich dir noch Schleifen, auch ein interessantes und vor allem wichtiges Thema in der Programmierung. In den nächsten Artikeln zeige Ich dir spezielle Befehle wie dist oder map, außerdem mathematische Funktionen wie PI, pow(), abs(), cos() und so weiter, es bleibt weiterhin spannend und mit jedem Artikel biete Ich dir mehr Wissen und somit mehr Möglichkeiten, mit Processing umzugehen und immer bessere Ergebnisse zu erzielen :-)

Bis dahin viel Spaß beim Lernen und noch einen schönen Tag
Marius