Schlagwort-Archiv: variable

Verschwindende Objekte – Processing und Arrays

Hi,

heute hab’ ich mich mal an eine Sache rangemacht die ich schon längst mal selbst in Processing realisieren wollte. Irgendwo hatte ich mal gesehen wie in einem Sketch eine Ellipse der Maus folgte, und diese dann Spuren hinterherzog die langsam verschwanden. Das fand ich ziemlich gut gemacht, und heute hatte ich spontan den Einfall, das selbst zu versuchen. Vorab möchte ich dir anhand eines Screenshots zeigen, wie es am Ende aussehen wird:

Verschwindende Formen

Verschwindende Formen

Ich schlage vor, wir fangen einfach mal an. Dafür muss aber erst einmal geklärt sein, was wir wollen und wie es funktioniert. Also was wollen wir, bzw. was will ich … ich will, dass Ellipsen meiner Maus folgen, diese aber mit der Zeit auf der Strecke kleiner werden bis sie weg sind. Aussehen wird es am Ende so wie in meinem Sketch auf OpenProcessing, hier der Sketch zum ausprobieren:

Bewege einfach mal die Maus um zu sehen was passiert. Drücke die Tasten 1, 2 oder 3 um den Modus für die Anzeige zu wechseln (klick’ vorher am besten einmal in den Sketch, damit dieser den Fokus hat).
Cool und wie funktioniert das?! …… also ich hab’ mir bei meinen Überlegungen gedacht wir brauchen auf jeden Fall schonmal temporäre Variablen, die nur dazu genutzt werden um die “alten” Ellipsen zu zeichnen, also die, die ich mit der Maus bereits abgefahren habe. Denn die werden ja dann mit der Zeit immer kleiner. Eine Variable wird dafür natürlich nicht reichen, wir brauchen eine für X und Y, damit wir die Ellipsen im Raum platzieren können. Und Variablen reichen dafür eh nicht, was wir brauchen sind Arrays. Würden wir nur eine Variable nehmen, dann könnten wir es höchstens noch gerade so machen, dass jede nachziehende Ellipse erst gezeichnet wird, wenn die vorherige komplett verschwunden ist, wir würden also im Endeffekt immer nur eine sehen. Und das wollen wir nicht, was wir wollen ist ja, dass überall dort wo wir mit der Maus sind/waren, Ellipsen auftauchen die dann wieder verschwinden (kleiner werden bis sie weg sind). Also ein Array in dem wir die X- und eines in dem wir die Y-Koordinaten ablegen.
Und du brauchst noch eine Variable “count”, die am Ende von void draw() immer um +1 hochgezählt wird. Die aktuellste, neueste Ellipse hat als Koordinaten im Array dann immer den größten Index, also “count”.

Bevor es daran geht, dafür zu sorgen dass die Ellipsen kleiner werden, musst du dir erst einmal vorstellen können, was bis dahin passiert. Wir bewegen quasi die Maus und zeichnen an jede Position, an dem die Maus ist, eine Ellipse. Klar kannst du’s auch ohne Array machen und lediglich ellipse(mouseX, mouseY, 50, 50); schreiben, allerdings würde dir das wenig bringen, am Anfang von void draw() wird immer background(0); ausgeführt, man würde davon also nichts sehen. Deswegen die Arrays, damit die Koordinaten aus dem Array in einer Schleife abgefragt, und die Ellipsen dann jedes mal neu gezeichnet werden können.
Lassen wir die Maus einmal folgende Koordinaten fahren:

Position 1: X=6 Y=193
Position 2: X=6 Y=192
Position 3: X=6 Y=191
Position 4: X=6 Y=190
Position 5: X=6 Y=189
Position 6: X=7 Y=189
Position 7: X=7 Y=188
Position 8: X=8 Y=188
Position 9: X=8 Y=187
Position 10: X=8 Y=186
Position 11: X=9 Y=186
Position 12: X=9 Y=185
Position 13: X=10 Y=184
Position 14: X=11 Y=182
Position 15: X=11 Y=181
Position 16: X=12 Y=180
Position 17: X=13 Y=179
Position 18: X=14 Y=178
Position 19: X=15 Y=176
Position 20: X=16 Y=175
Position 21: X=17 Y=174
Position 22: X=18 Y=173
Position 23: X=19 Y=173
Position 24: X=19 Y=172
Position 25: X=20 Y=172
Position 26: X=21 Y=171
Position 27: X=22 Y=171
Position 28: X=23 Y=170
Position 29: X=24 Y=169
Position 30: X=26 Y=169
Position 31: X=28 Y=168
Position 32: X=29 Y=168
Position 33: X=31 Y=167
Position 34: X=32 Y=167
Position 35: X=34 Y=167
Position 36: X=36 Y=166
Position 37: X=38 Y=166
Position 38: X=40 Y=166

Für dieses Beispiel hab ich die Maus einfach in paar Sekunden bewegt und die Koordinaten aufgezeichnet. Das sind also die einzelnen “Stationen” die die Maus abgefahren hat, und nun stell dir vor, dass diese Koordinaten jedes mal in ein Array geschrieben werden. Array für X-Koordinaten hätte an Index 0 also den Wert 6, das Array für Y-Koordinaten den Wert 193. Durch eine extra Variable (-> count) bestimmen wir noch den Index, der um 1 hochgezählt wird. Zu Anfangs lege ich für count den Wert 0 fest.

Schaun wir mal was void draw() macht:
count hat den Wert 0, Array (ich nenne die Arrays einfach mal X und Y) X hat an Index “count” (also Null) den Wert 6, Array Y hat an Index “count” (also Null) den Wert 193. Daraus folgt:
X[count] = 6
Y[count] = 193

Count wird um +1 hochgezählt:
count++;
void draw() ist am Ende angelangt, alles also wieder von vorn..
Nächster Durchlauf in void draw(), count hat mittlerweile den Wert 1, Array X bekommt an Index 1 (->count ist ja 1) den Wert 6, Array Y bekommt an Index 1 den Wert 192. count wird hochgezählt und hat jetz den Wert 2, void draw() ist am Ende, alles wieder von vorne …. und so weiter. Unser Array wird mit der Zeit ziemlich voll.

Aber zum wesentlichen: In einer Schleife wird das Array durchlaufen, logischerweise nur soweit wie das Array Werte hat, bzw. die Anzahl des Wertes der Variable “count”. In der Schleife dann werden die Ellipsen gezeichnet. Im Code sieht es dann in etwa so aus:

/**
 * Verschwindende Formen
 *
 * Dies soll anhand eines coolen Beispiels zeigen, was
 * man mit Arrays alles anstellen kann.
 *
 */

void setup()
{
  //Das Übliche, schwarzer Hintergrund, Größe und smooth
  size(300, 300);
  background(0);
  smooth();
}

//Variablen für temporäre (!) Koordinaten und Größe der Formen
int tpx[] = new int[100];
int tpy[] = new int[100];
//Count wird in void draw() kontinuierlich inkrementiert
int count = 0;

void draw()
{
  //Hintergrund neu zeichnen und aussehen der Objekte angeben
  background(0);
  noStroke();
  fill(#ffffff, 127);
  //Die Koordinaten des aktuellen (neuesten) Objekts
  //werden festgelegt
  tpx[count] = mouseX;
  tpy[count] = mouseY;

  //In der Schleife werden nun alle Objekte bis zum aktuellen
  //Höchstwert durchlaufen (count wird je um 1 erhöht, siehe
  //letzte Zeile in void draw()
  for (int i = 0; i < count; i++)
  {
    noStroke();
    //Die Ellipsen werden gezeichnet
    ellipse(tpx[i], tpy[i], 50, 50);
  }


  //Zum Schluss wird diese Variable noch um +1 inkrementiert
  count++;
}

Du siehst die zwei temporären Arrays für X- und Y-Koordinaten tpx und tpy und die Variable count. In der Schleife in draw() geht’s dann los, die Werte werden aus dem Array geholt, mit diesen Werten werden die Ellipsen gezeichnet. Mit der Zeit (also nach jedem Durchlauf von draw()) kommt in das Array immer mehr rein. Tja, jetzt führe den Sketch doch mal aus und schau was passiert…
Dir wird aufgefallen sein, dass mir, wenn ich für die Größe des Arrays eine feste Angabe machen, Processing irgendwann eine “ArrayIndexOutOfBoundsException” werfen wird. In diesem Beispiel habe ich 100 genommen. Ich könnte jetzt auch 1000 nehmen oder 100000, dann hätten wir zwar mehr Zeit uns unser Ergebnis anzusehen, trotzdem wird es irgendwann abbrechen weil “count” die maximal angegebene Größe des Arrays (hier 100) überschreitet.
Es gibt aber natürlich Möglichkeiten, dem entgegenzuwirken, beispielsweise indem wir einfach das Array jedes mal erweitern. Das heißt ich setzte in meinem Beispiel die maximale Größe des Arrays immer auf -sagen wir mal zwei- Werte mehr als count – der Sketch würde also unendlich lange laufen (naja, fast..) wenn wir so wollen.
In dem Zuge lernst du also auch gleich den Befehl expand() kennen. Mit dem kannst du Arrays erweitern. Folgender Code bringt uns zu in dieser Richtung zum Ziel:

/**
 * Verschwindende Formen
 *
 * Dies soll anhand eines coolen Beispiels zeigen, was
 * man mit Arrays alles anstellen kann.
 *
 */

void setup()
{
  //Das Übliche, schwarzer Hintergrund, Größe und smooth
  size(300, 300);
  background(0);
  smooth();
}

//Variablen für temporäre (!) Koordinaten und Größe der Formen
int tpx[] = new int[1];
int tpy[] = new int[1];
//Count wird in void draw() kontinuierlich inkrementiert
int count = 0;

void draw()
{
  //Hintergrund neu zeichnen und aussehen der Objekte angeben
  background(0);
  noStroke();
  fill(#ffffff, 127);
  //Die Koordinaten des aktuellen (neuesten) Objekts
  //werden festgelegt
  tpx[count] = mouseX;
  tpy[count] = mouseY;

  //In der Schleife werden nun alle Objekte bis zum aktuellen
  //Höchstwert durchlaufen (count wird je um 1 erhöht, siehe
  //letzte Zeile in void draw()
  for (int i = 0; i < count; i++)
  {
    noStroke();
    //Die Ellipsen werden gezeichnet
    ellipse(tpx[i], tpy[i], 50, 50);
  }
  //Array wird immer um 2 mehr als count erweitert
  tpx = expand(tpx, count+2);
  tpy = expand(tpy, count+2);

  //Zum Schluss wird diese Variable noch um +1 inkrementiert
  count++;
}

Und schon klappt es. So, jetzt haben wir es geschafft, dass an allen Positionen an denen wir mit der Maus waren, Ellipsen gezeichnet werden. Du wirst dich vielleicht noch fragen, wieso wir vor der Schleife noch sagen, dass tpx[count] und tpy[count] jeweils mouseX und mouseY als Wert haben. Diese Werte werden ja nämlich nur ein mal zugewiesen, deswegen bleiben die Ellipsen auch auf ihren Positionen. Die neueste Ellipse (am höchsten Index, und der Index ist immer der Wert von count) bekommt als Werte mouseX und mouseY, am Ende von draw() wird count wieder um +1 erhöht. Sagen wir count hat den Wert 27, dann würden wir im Code sinngemäß folgende Zuweisung machen:
tpx[27] = mouseX;
tpy[27] = mouseY;
Jetzt wird count am Ende hochgezählt, ist nun also bei 28. Der Wert im Array an Index 27 wird also nun nie wieder angerührt und bekommt keine Wertzuweisung mehr. Durch die for-Schleife wird die Ellipse zwar jedes Mal neu gezeichnet, allerdings wird sich die Position nicht mehr verändern. Und jetzt geht’s nämlich darum, dass die Teile kleiner werden.

Für diesen Effekt brauchst du wieder die Arrays, in welche wir die Größe der Ellipse speichern. Anders als bei den Arrays für die Koordinaten brauchst du hiear aber nur eines, denn ich möchte für Breite und Höhe der Ellipsen immer dieselben Werte haben, quasi also runde Kreise ;-)
Den Anfangswert (wie für X und Y ja mouseX und mouseY festgelegt sind) weise ich dem Array für den Index wieder über die count-Variable zu. Ich hab’ spontan einfach einmal den Wert 50 für die Größe unserer Ellipse gewählt.
Aber wie geht’s jetzt weiter? Also erreichen möchten wir ja, dass die Ellipsen kleiner werden. Da alle Ellipsen ja immer dort neugezeichnet werden, wo die Maus schonmal langgefahren ist, könnten wir eigentlich genauso einfach in der for-Schleife angeben, dass für Größe[i] immer kleiner wird… machen wir das mal, in meinem Sketch heißt die Variable für die Größe der Ellipsen “ts”:

/**
 * Verschwindende Formen
 *
 * Dies soll anhand eines coolen Beispiels zeigen, was
 * man mit Arrays alles anstellen kann.
 *
 */

void setup()
{
  //Das Übliche, schwarzer Hintergrund, Größe und smooth
  size(300, 300);
  background(0);
  smooth();
}

//Variablen für temporäre (!) Koordinaten und Größe der Formen
int tpx[] = new int[1];
int tpy[] = new int[1];
float ts[] = new float[1];
//Count wird in void draw() kontinuierlich inkrementiert
int count = 0;
//Eine Variable um die Ansicht zwischen Ellipse und Rechteck zu wechseln
int form = 1;

void draw()
{
  //Hintergrund neu zeichnen und aussehen der Objekte angeben
  background(0);
  noStroke();
  fill(#ffffff, 127);
  //Die Koordinaten des aktuellen (neuesten) Objekts
  //werden festgelegt
  tpx[count] = mouseX;
  tpy[count] = mouseY;
  //Ausgangsgröße der Form (Ellipse, etc..)
  ts[count] = 50;

  //In der Schleife werden nun alle Objekte bis zum aktuellen
  //Höchstwert durchlaufen (count wird je um 1 erhöht, siehe
  //letzte Zeile in void draw()
  for (int i = 0; i < count; i++)
  {
    noStroke();
    //Die Ellipsen werden gezeichnet
    ellipse(tpx[i], tpy[i], ts[i], ts[i]);
    //Faktor, um den das Objekt kleiner wird - bestimmt
    //auch Geschwindigkeit. Hier wird immer um 1 verkleinert
    ts[i] -= 1;
  }

  //Hier werden die Arrays erweitert, und zwar immer um 
  //jeweils 2 mehr als count
  tpx = expand(tpx, count+2);
  tpy = expand(tpy, count+2);
  ts = expand(ts, count+2);

  //Zum Schluss wird diese Variable noch um +1 inkrementiert
  count++;
}

So, jetzt lass den Sketch mal laufen …. ich weiß was passiert, du wirst denken du hättest es endlich geschafft, doch nach wenigen Sekunden wirst du bemerken, dass da etwas noch gehörig schief läuft! Klar, die Ellipsen werden kleiner, allerdings hab ich an keiner Stelle im Code festgelegt was passieren soll wenn die Größe unter Null liegt, dann bekommen wir nämlich negative Werte. Processing nimmt das Vorzeichen (Minus) einfach weg und die Kreise werden wieder größer, und nach etwa 7 Sekunden wird der Sketch saumäßig lahm. Wenigstens ist dir noch aufgefallen, was der Fehler ist. Und mit einer einfachen If-Bedingung fragst du noch ab, ob die Größe (ts) größer oder kleiner als Null ist. Oder anders herum -so wie ich es gemacht habe- soll Variable ts nur heruntergezählt werden, wenn ts größer als Null ist. Ergänze deinen Code nun also noch um diese Abfrage und der Sketch ist so wie er ist fertig:

/**
 * Verschwindende Formen
 *
 * Dies soll anhand eines coolen Beispiels zeigen, was
 * man mit Arrays alles anstellen kann.
 *
 */

void setup()
{
  //Das Übliche, schwarzer Hintergrund, Größe und smooth
  size(300, 300);
  background(0);
  smooth();
}

//Variablen für temporäre (!) Koordinaten und Größe der Formen
int tpx[] = new int[1];
int tpy[] = new int[1];
float ts[] = new float[1];
//Count wird in void draw() kontinuierlich inkrementiert
int count = 0;
//Eine Variable um die Ansicht zwischen Ellipse und Rechteck zu wechseln
int form = 1;

void draw()
{
  //Hintergrund neu zeichnen und aussehen der Objekte angeben
  background(0);
  noStroke();
  fill(#ffffff, 127);
  //Die Koordinaten des aktuellen (neuesten) Objekts
  //werden festgelegt
  tpx[count] = mouseX;
  tpy[count] = mouseY;
  //Ausgangsgröße der Form (Ellipse, etc..)
  ts[count] = 50;

  //In der Schleife werden nun alle Objekte bis zum aktuellen
  //Höchstwert durchlaufen (count wird je um 1 erhöht, siehe
  //letzte Zeile in void draw()
  for (int i = 0; i < count; i++)
  {
    noStroke();
    //Die Ellipsen werden gezeichnet
    ellipse(tpx[i], tpy[i], ts[i], ts[i]);

    //Solange die Größe des Objekts größer als Null
    //ist, kann das Objekt verkleinert werden, sobald es
    //kleiner ist als Null, passiert einfach nichts mehr
    if (ts[i] > 0)
    {
      //Faktor, um den das Objekt kleiner wird - bestimmt
      //auch Geschwindigkeit. Hier wird immer um 1 verkleinert
      ts[i] -= 1;
    }
  }

  //Hier werden die Arrays erweitert, und zwar immer um 
  //jeweils 2 mehr als count
  tpx = expand(tpx, count+2);
  tpy = expand(tpy, count+2);
  ts = expand(ts, count+2);

  //Zum Schluss wird diese Variable noch um +1 inkrementiert
  count++;
}

Und -du hast es bestimmt gesehen- nicht vergessen, das Array “ti” wieder zu erweitern ;-) So sieht es doch ziemlich geil aus, finde ich.

Nicht relevant, aber gut zu wissen:
Wenn du aufmerksam bist und gut rechnen kannst ist dir vielleicht noch etwas aufgefallen… Du kannst angeben, um wieviel die Größe jedes mal verringert wird. Im eben gezeigten Sketch habe ich den Wert 1. Wenn du aber zum Beispiel 0.75 wählst, ziehst du Punkte hinter dir her, die nicht mehr verschwinden. Wenn du für background weiß wählst (background(255);) und für Füllfarbe Schwarz (fill(0);), kannst du es genauer beobachten. Versuche dabei, die Maus nur langsam zu bewegen. Das passiert, weil du Ellipsen mit dem Anfangswert 50 zeichnest. Wenn du nun ständig 0.75 abziehst, hast du irgendwann am Ende zu den Wert 1.25, davon dann nochmal 0.75 weg ergibt 0.5, davon nochmal 0.75 weg ergibt -0.25 -> HA, eine negative Zahl, und wie du weißt macht Processing daraus einfach eine positive. Du hast zwei Möglichkeiten. Und zwar musst du als Anfangswert eine Zahl wählen, die -wenn von ihr ja ständig 0.75 abgezogen werden- irgendwann dann genau 0.00 ergibt. Der Wert 50.25 würde beispielsweise funktionieren, wenn von diesem immer wieder 0.75 abgezogen werden, würde am Ende genau 0.00 herauskommen.
Die andere Möglichkeit ist, mit else abzufragen ob ts[i] kleiner(!) als 0 ist, also eine negative Zahl, und dann zu ts[i] einfach die Differenz hinzuzuaddieren. Dann ist es auch egal, was du als Anfangswert übergibst.

Ja, das wär’s für heute mal wieder, hoffe ich konnte dir einige interessante Dinge zeigen. Abschließend hier noch der komplette Code. Bei dem hier kannst du nun die Tasten 1, 2 oder 3 drücken, um zwischen Ellipse, Rechteck und Linie zu wechseln. Übrigens habe ich hier auch die else-Abfrage noch hinzugefügt, damit ts[i] am Ende immer 0.00 ist ;-)

/**
 * Verschwindende Formen
 *
 * Dies soll anhand eines coolen Beispiels zeigen, was
 * man mit Arrays alles anstellen kann.
 *
 */

void setup()
{
  //Das Übliche, schwarzer Hintergrund, Größe und smooth
  size(300, 300);
  background(255);
  smooth();
}

//Variablen für temporäre (!) Koordinaten und Größe der Formen
int tpx[] = new int[1];
int tpy[] = new int[1];
float ts[] = new float[1];
//Count wird in void draw() kontinuierlich inkrementiert
int count = 0;
//Eine Variable um die Ansicht zwischen Ellipse und Rechteck zu wechseln
int form = 1;

void draw()
{
  //Hintergrund neu zeichnen und aussehen der Objekte angeben
  background(255);
  noStroke();
  fill(0, 127);
  //Die Koordinaten des aktuellen (neuesten) Objekts
  //werden festgelegt
  tpx[count] = mouseX;
  tpy[count] = mouseY;
  //Ausgangsgröße der Form (Ellipse, etc..)
  ts[count] = 50;

  //In der Schleife werden nun alle Objekte bis zum aktuellen
  //Höchstwert durchlaufen (count wird je um 1 erhöht, siehe
  //letzte Zeile in void draw()
  for (int i = 0; i < count; i++)
  {
    noStroke();
    //Je nachdem welchen Wert "form" hat zeichnen wir ...
    switch(form)
    {
    case 1:
      //..eine Ellipse oder..
      ellipse(tpx[i], tpy[i], ts[i], ts[i]);
      break;
    case 2:
      //..ein Rechteck oder..
      rectMode(CENTER);
      rect(tpx[i], tpy[i], ts[i], ts[i]);
      break;
    case 3:
      //..eine Linie. Und eine Linie nur, wenn Variable "ts" mit diesem
      //Index noch größer ist als Null. Ansonsten würde die Linie nicht
      //verschwinden
      if (i > 1 && ts[i] > 0)
      {
        stroke(0);
        line(tpx[i], tpy[i], tpx[i-1], tpy[i-1]);
      }
      break;
    }
    //Solange die Größe des Objekts größer als Null
    //ist, kann das Objekt verkleinert werden, sobald es
    //kleiner ist als Null, passiert einfach nichts mehr
    if (ts[i] > 0)
    {
      //Faktor, um den das Objekt kleiner wird - bestimmt
      //auch Geschwindigkeit. Hier wird immer um 1 verkleinert
      ts[i] -= 0.75;
    }
    else
    {
      float tmp = 0 - ts[i];
      ts[i] += tmp;
    }
  }

  //Hier werden die Arrays erweitert, und zwar immer um 
  //jeweils 2 mehr als count
  tpx = expand(tpx, count+2);
  tpy = expand(tpy, count+2);
  ts = expand(ts, count+2);

  //Zum Schluss wird diese Variable noch um +1 inkrementiert
  count++;
}

void keyPressed()
{
  //Wir verändern die Variable "form", um zwischen Ellipse, Rechteck
  //und Linie zu wechseln. In void draw() wird abgefragt dass wenn
  //form == 1 eine Ellipse, wenn form == 2 ein Rechteck und wenn 
  //form == 3 eine Linie gezeichnet wird.
  switch(key)
  {
  case '1':
    form = 1;
    break;
  case '2':
    form = 2;
    break;
  case '3':
    form = 3;
    break;
  }
  //Arrayindex wird zurückgesetzt
  count = 0;
}

Du kannst als Anfangswerte auch mal Zufallszahlen übergeben, sieht auch nicht schlecht aus, ändere die Zeile einfach in:

  ts[count] = random(100);

Oder du änderst den Alphawert, oder machst zufällige Farben oder machst die Formen mit Rand …. experimentier’ einfach, wie gesagt, irgendwas wird schon dabei herauskommen ;-)

Bis dahin
Marius

Variablen, Arrays und Modifier in Processing

Hi,

so, Ich hab im letzten Artikel eigentlich Klassen angekündigt, aber dann dachte ich mir ist es sicherlich klüger wenn zuerst die Arrays zu sprache kommen. Außerdem sind Arrays ebenso wichtig.
Arrays also .. aber was ist das? Eigentlich dasselbe wie eine Variable, nur dass mehrere Werte gespeichert werden können. Wir haben uns Variablen damals als Schachteln vorgestellt, stellen wir uns Arrays also eher als Regal vor in welches mehrere Werte abgelegt werden können. Zur Veranschaulichung:

Eine Variable hat also einen Namen, einen Datentyp und einen Wert:

Es gibt noch was das eine Variable hat. Es ist nicht sichtbar und wird nicht (direkt) mit dazugeschrieben. Kommst du drauf? Es ist der Modifier, also der Gültigkeitsbereich einer Variable. Bei Arrays ist das übrigens genauso. Eine Variable die in einer Funktion deklariert wurde ist auch nur in dieser Funktion gültig. Eine Variable die innerhalb einer Klasse deklariert wurde ist Klassenweit gültig und kann Klassenübergreifend nur über eine Objektinstanz der Klasse angesprochen werden, dazu aber im nächsten Artikel mehr. Zurück zum Thema, eine Variable die außerhalb von Funktionen (also innerhalb der Klasse, so wie du es bisher gemacht hast) deklariert wurden können auch von überall aus (auch in einer Funktion) verändert werden, die Änderung wirkt sich auf die globale Variable aus und jede Funktion die auf diese Variable zurückgreift arbeitet mit der geänderten Variable weiter. Und wie gesagt, mit Arrays verhält es sich genauso.

Jetzt hast du bis jetzt noch kein Stück Code gesehen, wollen wir also in die Praxis übergehen ;-)
Zuerst stellt sich natürlich die Frage wie man ein Array deklariert. Schauen wir uns das einmal an:

Gar nicht so schwer oder =) Das Array in diesem Beispiel kann insgesamt 13 Werte speichern, da der Index bei 0 beginnt. An einem Beispiel welches ohne Arrays gar nicht möglich wäre will Ich dir das demonstrieren. Stell dir vor du klickst in einem Sketch an irgendeinem Punkt und es erscheint eine ellipse. Dann klickst du nochmal an anderer Stelle, noch eine Ellipse erscheint und beide Ellipsen werden durch eine Linie verbunden. Dann klickst du nochmals irgendwohin, eine neue ellipse erscheint und eine Linie vom letzten und vom ersten Kreis werden zum neuen gezeichnet. Und das immer so weiter, verstehst du worauf das hinausläuft? Zwischen allen Punkten werden Linien verbunden, sodass immer jeder Punkt mit jedem anderen durch eine Linie miteinander verbunden wird. Das werden bei 3 Punkten 3 Linien, bei vier Punkten schon 6 Linien (die Diagnoalen nicht vergessen ;-) ) und so weiter. Das werden mit der Zeit ziemlich viele werden =) Egal, jedenfalls braucht es dafür ein Array. In dieses werden alle Mauskoordinaten gespeichert, jedes mal wenn du klickst. So kann eine Schleife durchlaufen werden in der noch eine Schleife durchlaufen wird, in der alle Punkte (die Koordinaten also) abgefragt und demnach Linien gezeigt werden. 2 Schleifen? Sicher, wir haben ja x und y Koordinaten, also hab Ich dafür auch 2 Arrays hergenommen. Dazu brauchen wir einen counter der jedesmal um 1 hochgezählt wird, damit wir immer wissen welches der letzte Punkt war.

Schau dir das einfach mal an:

void setup()
{
  smooth();
  size(300, 300);
  background(#000000);
  strokeWeight(1);
}

int[] x = new int[10000];
int[] y = new int[10000];
int c = 0;

void draw()
{
  
}

void mouseClicked()
{
  x[c] = mouseX;
  y[c] = mouseY;
  stroke(255);
  if(c != 0)
  {
    line(mouseX, mouseY, x[c-1], y[c-1]);
    for(int i = 0; i < c+1; i++)
    {
      for(int j = 0; j < c+1; j++)
      {
        line(x[i], y[i], x[j], y[j]);
      }
    }
  }
  stroke(0);
  ellipse(mouseX, mouseY, 10, 10);
  c++;
}

Wenn du diese Verbindungen der Punkte untereinander nicht willst sondern einfach nur die Linien zum jeweils nächsten Punkt, kannst du die Schleifen raus lassen, also so:

void setup()
{
  smooth();
  size(300, 300);
  background(#000000);
  strokeWeight(1);
}

int[] x = new int[10000];
int[] y = new int[10000];
int c = 0;

void draw()
{
}

void mouseClicked()
{
  x[c] = mouseX;
  y[c] = mouseY;
  stroke(255);
  if (c != 0)
  {
    line(mouseX, mouseY, x[c-1], y[c-1]);
  }
  stroke(0);
  ellipse(mouseX, mouseY, 10, 10);
  c++;
}

Ich habe als maximale Anzahl an Werten für das Array 10.000 angegeben, noch schöner ist es natürlich wenn wir zuerst mit weniger deklarieren (zum Beispiel nur 5) und dann nach jedem Klick das Array erweitern, aber das ist wieder eine andere Sache.
Mit Arrays kann man in Verbindung mit Klassen noch viel tollere Sachen anstellen. Dazu mehr im kommenden Artikel =)

Bis dahin
Marius

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

processing

Processing – Variablen, Datentypen, Operatoren

Hi,

jetzt wird’s langsam richtig spannend. In Kürze wirst du phantastische Effekte zustande bringen können. Das können wir nur dadurch erreichen, indem wir das Programm dynamisch gestalten und mit Variablen arbeiten. Variablen – merk dir das gut, denn damit wirst du ab sofort täglich zu tun haben, ein Programm ohne Variablen macht schon fast gar keinen Sinn.

Doch wollen wir uns zuallererst einmal ansehen ..

Was Variablen sind

Wie immer ist für mich schwierig, etwas zu erklären, ohne zu wissen, welchen Kenntnisstand du ungefähr hast, besonders was Programmierung angeht. Variablen, was stellt man sich darunter vor? Variablen -> variabel, also flexibel, veränderbar. Wollen doch mal sehen, wie Wikipedia Variablen erklärt:

In der Programmierung ist eine Variable im allgemeinsten Sinne einfach ein Behälter für Rechnungsgrößen („Werte“), die im Verlauf eines Rechenprozesses auftreten. Im Normalfall wird eine Variable durch einen Namen bezeichnet und hat eine bestimmte Adresse im Speicher des Rechners.

Damit ist eigentlich alles gesagt. Aber was stellt man sich darunter vor? Ich versuche es einmal mit eigenen Worten zu erklären. Stell dir eine Variable als eine leere Hülle vor, oder eine Schachtel. Du kannst die Schachtel nun mit beliebigen Dingen füllen. Du hast beim Start des Programmes keine Schachteln, die musst du dir erstellen. Das bedeutet, du kannst zu Anfangs deine Schachteln oder Kartons bereitstellen und mit Sachen befüllen, du kannst auch während das Programm ausgeführt wird immer wieder Dinge aus der Schachtel nehmen, Dinge hinzufügen oder alles aus der Schachtel herausnehmen. Deine Schachteln sind immer beschriftet, sodass du gleich weißt, wo du was machen / herausnehmen oder hineinlegen sollst.
Am Beispiel von Variablen könnte man das nun so erklären: Du deklarierst eine Variable (deklarieren bedeutet, dass du dir die Variable schon einmal zur Verfügung stellst, ganz gleich, was du nun jetzt oder später noch damit hast, sie muss aber auf jeden Fall da sein). Dieses deklarieren geschieht in etwa so: Du legst fest, welche Art von Werten die Variable aufnehmen kann, und wählst einen Namen für diese Variable. Du kannst immer nur bestimmte Werte in Variablen speichern, so wird dann zwischen den verschiedenen sogenannten “Datentypen” unterschieden. Du kannst die Variable nun deklarieren, und Ihr gleich zu anfangs einen Wert zuweisen, oder auch später, wie du möchtest.

Ich zeige dir das einmal anhand dreier simpler Codezeile:

Sourcecode
  int Zahl;
  Zahl = 4;
  int Zahl2 = 12;

Damit kannst du noch nicht viel anfangen, aber dir wird gleich einiges klar werden, wenn wir das Beispiel von diesem Code anhand einer Grafik deutlich machen:


Lies bitte zuerst diesen Wikipedia Eintrag zu Datentypen durch, besonders der Absatz “Elementare Datentypen” ist interessant.

Wenn du das gelesen hast, können wir hier weitermachen. Ich stelle dir einmal die 3 gebräuchlichsten Datentypen vor, die für den Anfang am öftesten vorkommen werden, nämlich int, float und string. Klingt seltsam, und was bedeutet das?
int steht für Integer, also Ganzzahl. Variablen die mit diesem Datentypen deklariert werden, können Ganzzahlige Werte annehmen. Dann haben wir noch float, um Fließkommazahlen zu speichern, also Kommazahlen eben. Und dann noch String (zu Deutsch “Zeichenfolge”), um Text aufzunehmen.
Die schreibweise ist hierbei relativ leicht, du suchst dir den Datentyp aus, legst einen Namen fest und übergibst einen Wert mit dem Zuweisungsoperator “=”. Bei int und float schreibst du als Wert einfach die Zahl. Bei Strings schreibst du als Wert den Text, eingeschlossen in zwei Anführungszeichen, das ist wichtig. Sehen wir uns noch die Schreibweise an, Ich zeige dir ein Stück Code, welcher relativ einfach zu verstehen ist. Danach gehen wir auf die Operatoren ein, damit wir damit auch ordentlich was machen können :-)

Sourcecode
int Zahl = 12;
float Kommazahl = 5.21;
float Kommazahl2;
String zeichenfolge = "Hallo";
String Zeichenfolge2;

void setup()
{
  size(300, 300);
  Kommazahl2 = 56.074;
  zeichenfolge2 = "Noch ein Text";
  int NeueZahl = 82;
}

Du siehst, es ist ganz einfach. Bevor wir nun gleich zu den Operatoren kommen, nun noch eine Schreibweise, du hast nämlich auch die Möglichkeit, mehrere Variablen getrennt durch Komma in einer Zeile zu deklarieren. Dabei kannst du ihnen aber keinen Wert zuweisen:

Sourcecode
int Zahl, Zahl2, Zahl3;
float Kommazahl1, Kommazahl2;
String text1, text2;

void setup()
{
  size(300, 300);
  Zahl = 3;
  Zahl2 = 99;
  Zahl3 = 32423;
  Kommazahl1 = 43.01;
  Kommazahl2 = 0.002;
  text1 = "Das ist ein Text";
  text2 = "Das ist noch ein Text";
}

Nun zu den ..

Operatoren

Operatoren kennst du, jeder kennt Operatoren. Damit meine Ich speziell Rechenoperatoren. Du kennst Rechenoperatoren schon, es gibt aber auch Vergleichs- oder Zuweisungsoperatoren. Und das kommt jetzt dran. Fangen wir an mit den

Rechenoperatoren

+
Logisch, Plus ist zum addieren da (2 + 5 = 7)
-
Minus zum subtrahieren (abziehen) (7 – 2 = 5)
*
Mal zum multiplizieren (2 * 5 = 10)
/
Teilen, also dividieren (10 / 5 = 2)
% (modulo)
Der Rest einer Division ==> 10 / 5 = 0 (also 10 geteilt durch 5 und 2, Rest 0, bedeutet 5 passt in 10 zwei mal rein, du hast keinen Rest) oder ==> 10 % 4 = 2 (10 geteilt durch 4 = 2 Rest 2, 4 passt in 10 zwei mal rein, du hast einen Rest von 2)

Sollte dir klar sein, brauchen wir nicht weiter ausschmücken, das kennst du. Was auch interessant ist, du kannst mit Klammern arbeiten, genauso wie damals (oder jetzt) in der Schule. Beispiel:

2 + 5 * 2 = 12
(2 + 5) * 2 = 20

Nichts leichter als das, du kannst damit beliebig lange Rechenoperationen durchführen, Ich will es dir anhand eines einfachen Codes einmal zeigen:

  int Ergebnis = ((2 + (2 * 4) * 4) - (12 / 2)) * 4;
  println(Ergebnis);

Ergibt 112. Ich zeig’ das kurz:
2 * 4 = 8
8 * 4 = 32
32 + 2 = 34
12 / 2 = 6
34 – 6 = 28
28 * 4 = 112;

Aber das nur als Beispiel ;-)
Zu weiteren mathematischen Spezialfunktionen kommen wir gleich. Sehen wir uns erst noch Vergleichsoperatoren an.

Vergleichsoperatoren

Vergleichsoperatoren sind, wie der Name schon sagt, zum Vergleich zweier Werte da. Beispiel: Ist 5 gleich 5? Ist 7 größer als 5? Ist 7 größer oder gleich 5? Ist 5 kleiner als 7? Sowas zum Beispiel. Was soll Ich dazu sagen, Ich darf wohl davon ausgehen, dass du das kannst. Hier noch eine Tabelle:

Operator Erklärung Beispiel
== Ist gleich 5 == 7 | trifft nicht zu
> Größer als 5 > 7 | trifft nicht zu
< Kleiner als 5 < 7 | trifft zu
>= Größer oder Gleich 5 >= 7 | trifft nicht zu
<= Kleiner oder Gleich 5 <= 7 | trifft nicht zu
!= Ist NICHT 5 != 7 | trifft zu

Das werden wir noch weiter vertiefen, wenn wir zu den Fallbedingungen kommen, also Wenn-Dann Abfragen. Im nächsten Artikel mehr dazu.

Zuweisungsoperatoren

Zuweisungsoperatoren sind dazu da, um Variablen einen Wert zuzuweisen. Das machst du mit dem “=”-Zeichen, wie du bereits weißt. Beispiel: int Zahl = 12; <== Variable "Zahl" wird der Wert 12 zugewiesen.

Inkrementieren und Dekrementieren
Inkrementierenbedeutet, eine Variable(natürlich nur Zahlen) um genau 1 zu erhöhen.
Beispiel:

  int Zahl =12;
  Zahl = Zahl + 1;
  //Du kannst auch schreiben:
  Zahl += 1;
  //Oder einfach:
  Zahl++;

Welche Schreibweise du wählst, liegt bei dir, aber Zahl++ ist weniger zum schreiben und sieht halt einfach geheimnisvoller aus ;-) Dasselbe funktioniert beim Dekrementieren, natürlich wird dann immer um 1 verringert, schau:

  int Zahl =12;
  Zahl = Zahl - 1;
  //Du kannst auch schreiben:
  Zahl -= 1;
  //Oder einfach:
  Zahl--;

Eigentlich ganz leicht. Das Inkrementieren wirst du die erste Zeit sicherlich verwenden, das kann Ich dir versprechen.
Es gibt auch noch logische Operatoren, diese kommen dann aber erst mit den Fallbedingungen zum Einsatz.

Bevor Ich mit meinem Artikel fertig bin, will Ich dich noch auf etwas hinweisen. Wie du Funktionen Werte gibst, weißt du ja mittlerweile (Beispiel: size(300, 300);). Stell aber sicher, dass du auch den richtigen Datentyp übergibst.
size(300.0, 300.0); wäre zwar dasselbe, würde aber nicht funktionieren, da Funktion “size()” einen Integer-Datentyp erwartet, und keine Fließkommazahl. Warum sage Ich dir das? Das sage Ich dir, weil es eine Möglichkeit gibt, einen Datentyp an einen anderen anzupassen. Klar, du wirst einen String(also Text) nicht in eine Zahl umwandeln können, aber du kannst den Wert eines float-Datentyps in integer wandeln.

size(int(300.0), int(300.0));

würde funktionieren, die Kommastellen werden einfach abgehackt.

Im nächsten Artikel will Ich dir Zufallszahlen und Fallbedingungen zeigen, wenn du das hast, weißt du schon eine Menge, sodass du nach dem nächsten Artikel mit Sicherheit schon schöne Dinge mit Processing anstellen kannst, es wird also spannend :-)

Bis dahin viel Spaß beim Lernen
Marius