Suche
preisvergleich_weiss

Recherche in 2.521.906 Produkten

Peter König 174

Processing: Programmieren für Anfänger

Die kostenlose Programmierumgebung Processing eignet sich wunderbar für den Einstieg – schon drei Zeilen Code reichen, damit sich auf dem Bildschirm etwas tut. Eine Anleitung Schritt für Schritt.

Mit der kostenlosen Programmierumgebung Processing bringen auch Anfänger mit wenigen Code-Zeilen komplizierte Vektorgrafiken und Animationen auf den Bildschirm oder verfremden Pixelbilder mit selbst ausgeknobelten Filtern. Strukturen aus zahlreichen zufällig verteilten Formen bilden dekorative Muster, ohne dass man sie mühsam im Zeichenprogramm zusammenklicken muss, denn mit Hilfe von Processing sind sie im Handumdrehen programmiert und als Vektorgrafik-Datei exportiert. Sogar die ersten Schritte in die 3D-Welt fallen mit Processing leicht.

Dies ist eine aktualisierte Version des Artikels "Kleinkunstprogramm", der zuerst in c't 24/2007 ab Seite 212 veröffentlicht wurde.

Da schon die erste Zeile Code auf Knopfdruck ein sichtbares Erfolgserlebnis produziert, setzen Design-Dozenten Processing schon seit Jahren in der Ausbildung ein. Processing verpackt die fertige Computerkunst auf Wunsch in ausführbare Anwendungen für Windows, Mac OS X und Linux. Inzwischen gibt es auch Erweiterungen für die Android-App-Programmierung sowie die JavaScript-Bibliothek p5.js, mit deren Hilfe man Processing-Apps in Webseiten einbinden kann – vor zehn Jahren exportierte man die eigenen Computerkunstwerke zu diesem Zweck noch als Java-Applets.

Die Demo eines interaktiven, rotierenden Gebirges findet man in Processing unter Beispiele/Demos/Graphics/Mesh Tweening ...
... die Planetensimulation mit Sonne, Merkur und Erde im selben Verzeichnis unter dem schlichten Namen Planets.

Kurzer Prozess

Dieser Applet-Export gelang seinerzeit reibungslos, weil Processing eigentlich gar keine eigene Programmiersprache, sondern nur eine pragmatische Verkleidung für Java ist. Seinen Code schreibt man prinzipiell in Java-Syntax. Zur Vereinfachung versteckt Processing freilich manche komplizierte Original-Operation in einen knappen Ein-Wort-Befehl: So speichert ein schlichtes save("bild.png") den aktuellen Inhalt des Programmfensters kurzerhand als Pixelgrafik.

Processing bietet aber nicht nur dank neuer Befehle manche praktische Abkürzung, man kann auch vieles Lästige weglassen, etwa Programm-Präludien à la Class MyClass { public static void main(String[] args) {..., die Anfänger verwirren und auch Routiniers nerven, wenn diese nur eben kurz was ausprobieren wollen. Gerade bei so einem kleinen Hack zwischendrin erfrischt die Konzentration aufs Wesentliche auch manchem Programmier-Profi das Herz. Dabei lässt Processing ihm Freiheiten: Man kann wahlweise imperativ oder objektorientiert programmieren – und auch beliebig schmutzig beides durcheinander. Wer weder mit dem einen noch mit dem anderen Begriff was anfangen kann, kommt trotzdem durch – mit etwas Geduld und dem Programmierparadigma "Versuch und Irrtum".

Die Schlichtheit seines Konzepts setzt dem Einsatz des Junior-Javas allerdings manche Grenzen – auf der Homepage des Projekts wie folgt ausgedrückt wird: "It enables the creation of software within a carefully designed set of contraints." Der Entwurf von GUI-Prototypen liegt offenbar außerhalb jener "sorgfältig gestalteten Einschränkungen" – fertige Vorlagen für Menüs und Knöpfe sucht man vergeblich, dazu muss man externe Bibliotheken wie controlP5 bemühen. Und die Suche nach Fehlern im Code bereitet mit den spartanischen Mitteln des Processing-Editors ab einer Programmlänge von 100 Zeilen keine Freude mehr – wenn sich da auch mit Erscheinen der Version Processing 3 einiges getan hat. Genau dort, wo der Spaß aufhört und ernsthafte Softwareentwicklung beginnt, sattelt man besser auf das Original-Java um und benutzt eine komfortable Programmierumgebung wie Eclipse. Um vorläufige, aber lauffähige Codeskizzen zu tippen oder gar die allerersten Programmierversuche überhaupt zu wagen, kann man hingegen getrost zum Processing-Editor greifen.

Abkupfern erlaubt

In welche Richtung solche ersten Schritte gehen könnten, zeigen die folgenden Codebeispiele. Der Reigen beginnt mit einem simplen Dreizeiler, der auch ohne jede Programmiererfahrung verständlich ist. Deutlich mehr Routine braucht man für interaktive Spiele, die gegen Ende Thema sind. Alle erwähnten Programme stehen als Zip-Archiv zum Download bereit – und können nach dem Import in die eigene Processing-Umgebung nach Herzenslust umgeschrieben, zerfleddert oder erweitert werden.

Processing gibt es kostenlos im Web für Windows, Mac OS X und Linux zum Download. Nach Auspacken des heruntergeladenen Archivs ist die Software ohne weitere Installation startklar. Eine separate Java-Umgebung einzurichten ist unter Windows nicht erforderlich, sofern man das Processing-Standardpaket auf den eigenen Rechner lädt.

Neben der eigentlichen Software bietet die (durchgehend englische) Processing-Homepage eine ausführliche Sprachreferenz, einführende Texte und jede Menge Beispielcode an. Was Processing-Fans mit dem Werkzeug in künstlerischer Hinsicht alles anstellen, findet man unter der Rubrik Exhibition.

Beim Programm Tree bestimmt der Mauszeiger, in welchem Winkel sich die Äste des stilisierten Baums gabeln.

Manche Beispiele sind auch fest in die Entwicklungsumgebung eingebaut. Man findet sie nach dem Programmstart im Menü unter Datei/Beispiele. Ein Mausklick auf einen Eintrag im dann aufklappenden Fenster lädt den Code des jeweiligen Beispiels in den Processing-Editor. Klickt man auf den Pfeil ganz links in der Symbolleiste, startet das Programm in einem neuen Fenster. Man beendet es, indem man dieses Fenster schließt oder den Stoppknopf in der Symbolleiste des Editors drückt.

Unter Basics liegen eine Reihe kurzer Codeskizzen, bei denen man manches Detail abspicken kann. Noch mehr Anregungen findet man in den anderen Verzeichnissen: Topics/Fractals and L-Systems/Tree etwa zeichnet einen Baum, sein Verzweigungswinkel hängt von der horizontalen Position des Mauszeigers ab. Bei Topics/Texture/TexturedSphere darf man wie bei Google Earth eine Weltkugel zum Rotieren bringen, Demos/Graphics/RotatingArcs animiert bunte, geometrische Formen, die entfernt an kinetische Kunstwerke der klassischen Moderne von Wladimir Tatlin oder Làszló Moholy-Nagy erinnern.

Getreu dem Konzept als Programmierkunst-Studio werden Programme in Processing konsequent als Skizzen ("Sketches") bezeichnet. Eine neue Programmskizze legt der Menüpunkt Datei/Neu an. Automatisch erhält sie einen Dateinamen nach dem Muster sketch_ mit angehängtem Datum und einem fortlaufenden Kleinbuchstaben. Datei/Speichern unter ... speichert das Programm unter einer selbst gewählten Bezeichnung. Beim Speichern legt Processing auf der Festplatte einen neuen Ordner mit dem Namen des Programms an, üblicherweise unter Eigene Dateien/Processing bei Windows, unter sketchbook im Home-Verzeichnis bei Linux und unter Dokumente/Processing auf dem Mac. Den Ort des eigenen "Skizzenbuchs" kann man über Datei/Einstellungen beliebig woanders hin verlegen. Die dort gelagerten Programme erreicht man über Datei/Sketchbook und ihren Namen. Will man fremde Programme öffnen, kopiert man sie entweder in ein passend benanntes Unterverzeichnis des Skizzenbuchs oder öffnet sie über den Dateidialog, den ein Klick auf Datei/Öffnen aufklappt. Processing-Code-Dateien tragen die Endung .PDE.

Malen nach Zahlen

Drei Programmzeilen reichen Processing aus, um ein neues Bildschirmfenster zu öffnen und die im Bild gezeigten Formen hineinzuzeichnen (Datei Linien.pde im Beispielcode):

size(400, 250);
rect(150, 80, 100, 100);
line(50, 50, 350, 200);

Die erste Zeile öffnet das Programmfenster mit einer Breite von 400 Pixeln und 250 Pixeln Höhe. Die zweite Zeile zeichnet ein Rechteck. Die vier Zahlen in der Klammer legen der Reihenfolge nach die x- und die y-Koordinate der linken oberen Ecke sowie die Breite und die Höhe fest.

Drei Zeilen Code reichen, damit Processing ein Programmfenster öffnet und zwei einfache Formen zeichnet.

Der Nullpunkt des Koordinatensystems liegt dabei stets in der linken oberen Ecke des Fensters (siehe Grafik). Das erste Pixel links oben trägt die Koordinaten (0,0), das letzte rechts unten (399, 249). Die schräge Linie schließlich wird durch die dritte Zeile definiert, sie beginnt beim Punkt mit den Koordinaten (50, 50) und endet bei (350, 200).

Das Koordinatensytem bei Processing beginnt oben links und mit der Koordinate 0 für das jeweils erste Pixel.

Jede Anweisung endet mit einem Semikolon. Text zwischen einem doppelten Schrägstrich und dem Zeilenende gilt als Kommentar und wird beim Ausführen des Programms einfach übersprungen. Die Anweisungen werden streng nach Reihenfolge im Programm abgearbeitet. Vertauscht man die zweite und dritte Zeile, verdeckt das Quadrat den Mittelteil der Linie.

Das nächste Programm namens Linien_1 zeichnet nacheinander 300 Linien. Dank einer Schleife, die Anweisungen mehrmals ausführt, kommt es dennoch mit vier Zeilen Code aus:

for (int i=0; i<300; i++){
line(random(width), random(height),
random(width), random(height));
}

Innerhalb der ersten runden Klammer definiert die erste Anweisung den Zähler namens i. Dieser ist vom Typ int, was für ganze Zahlen steht. Sein Startwert ist 0. Nach dem Semikolon folgt als zweite Anweisung ein Test, dessen Ergebnis bestimmt, ob die Schleife noch weiterlaufen soll. Hier ist dies der Fall, solange der Zähler kleiner als 300 ist. Er wird allerdings bei jedem Durchgang um eins erhöht, was die dritte Anweisung innerhalb der runden Klammer festlegt: i++ ist die in vielen Programmiersprachen übliche Kurzschreibweise für "addiere eins zu i hinzu".

Dank einer Schleife benötigt das Beispielprogramm zum Zeichnen von 300 zufällig platzierten Linien lediglich vier Zeilen Code.

Bei jedem Durchlauf der Schleife führt das Programm die Anweisungen zwischen den folgenden geschweiften Klammern einmal aus. Hier zeichnet es jeweils eine neue Linie, deren Anfangs- und Endpunkte die Funktion random() zufällig bestimmt. Die Zahl in der Klammer legt die Obergrenze der Zufallswerte fest, die Untergrenze ist 0. Die Zufallszahl kann dabei den Wert der Untergrenze tragen, aber sie ist stets kleiner als die obere Grenze.

Als Obergrenze der Zufallszahlen dienen hier die Variablen width und height. In sie setzt Processing automatisch die Breite und die Höhe des Programmfensters ein. Die zufälligen Linien liegen damit stets innerhalb des Fensters.

Farbkasten

Standardmäßig zeichnet Processing alle Linien und Konturen schwarz und die Flächen weiß auf einen grauen Hintergrund. Auf Dauer ist das langweilig. Der Befehl background(x) färbt den Hintergrund um, für Flächen und Linien sind fill(x) und stroke(x) zuständig. Der Platzhalter x steht dabei für eine Farbe, die wahlweise eine, zwei, drei oder vier Zahlen zwischen 0 und 255 festlegen: Eine einzelne Zahl bestimmt eine Graustufe, bei zweien steht die erste für den Grauwert, die zweite definiert die Deckkraft. Drei Zahlen stehen für die Farbkanäle Rot, Grün und Blau des RGB-Modells. Vier Zahlen schließlich legen eine RGB-Farbe und deren Deckkraft fest. Bei der Farbwahl hilft eine Palette, die Tools/Farbauswahl öffnet.

Das Programm Linien_2 funktioniert im Prinzip genauso wie Linien_1. Die Programmzeilen

background(255);
stroke(0, 100);
strokeWeight(2);
smooth();

stellen die Linien lediglich attraktiver dar. Sie erscheinen halb transparent vor weißem Hintergrund, ihre Breite beträgt zwei Pixel, und smooth() glättet die zuvor sichtbaren Pixeltreppen mittels Anti-Aliasing. Der Startpunkt der Linien liegt wie gehabt an einem beliebigen Ort im Programmfenster, die Koordinaten der Linien-Endpunkte beschränkt das Programm allerdings auf Werte zwischen einem Viertel und drei Vierteln der Fensterhöhe und -breite. Dadurch verdichten sich die Linien zum Zentrum hin. Zu diesem Zweck übergibt man random() zwei Werte, von denen der erste als Unter- und der zweite als Obergrenze zählt.

Dank des Zufallselements zaubert Processing bei jedem Programmstart ein neues Bild auf den Schirm. Spielt man mit Parametern wie Zahl der Schleifendurchläufe, Linientransparenz und -breite, Fenstergröße oder Farben, ändert das Ergebnis seinen Charakter.

Kleine Änderungen im Code führen bei Processing oft zu großen Unterschieden in der Wirkung. Diese beiden Programme ...
... unterscheiden sich nur in der Zahl und der Farbe der zufällig gezeichneten Linien sowie im Ton des Hintergrunds.

Linien_3 zeichnet 20.000 Linien (was je nach Hardware etwas dauern kann), die deutlich transparenter sind als in der vorigen Skizze. Der Bildcharakter wandelt sich dadurch von einem zur Mitte hin verdichteten Liniengespinst zu einem Farbrechteck, das am Rand wellig ausfranst – dank eines Moiré-Effekts.

Stars 'n' Stripes

Processing kann auch Mathe: Bogenmaßwinkeln etwa rückt man trigonometrisch per sin() und cos() zu Leibe. Beides benutzt das Programm Stern_1, um vom Mittelpunkt des Fensters aus Strahlen in zufällige Richtungen zu zeichnen.

winkel = random(2*PI);

bestimmt einen zufälligen Winkel zwischen null und dem Doppelten der Kreiszahl PI, was einem Vollkreis oder 360° entspricht. Da die Variable winkel auch andere Werte als ganze Zahlen speichern muss, ist ihr Typ als Gleitkommazahl (float) definiert. Die Länge des einzelnen Strahls bestimmt

laenge = random(min(width/2, height/2));

Diese liegt zwischen null und dem Minimum von halber Höhe und Breite des Fensters. Damit ist sichergestellt, dass keiner der Strahlen über den Rand des Bilds hinausragt. Den waagerechten Versatz des Endpunkts dx zwischen Anfangs- und Endpunkt des Strahls berechnet cos(winkel)*laenge, die Sinusfunktion liefert die senkrechte Komponente dy. Den Strahl von der Mitte des Programmfensters aus hin zum errechneten Endpunkt zeichnet schließlich die Zeile

line (width/2, height/2, width/2+dx, height/2-dy);

Warum man hier dx hinzuzählen, dy hingegen abziehen muss, zeigt die folgende Grafik:

Mit Hilfe trigonometrischer Funktionen berechnet Processing aus einem zufälligen Winkel und einer zufälligen Länge den Endpunkt eines Strahls, der vom Mittelpunkt des Fensters ausgeht.
Zweihundert Mal wiederholt entsteht aus diesem Algorithmus eine Supernova.

Für den Bildschirm rechnet die Processing-Laufzeitumgebung ihre Bilder in Pixel um, sie kann diese aber auch in ein Vektorgrafikformat schreiben. Dazu importiert man die mitgelieferte PDF-Bibliothek über Sketch/Library importieren/PDF Export. Dadurch taucht am Anfang der Programmdatei folgende Zeile auf:

import processing.pdf.*;

Alle Objekte, die zwischen den Befehlen beginRecord(PDF, "Dateiname.pdf") und endRecord() gezeichnet werden, finden sich anschließend als Vektorgrafik im PDF mit dem vorgegebenen Dateinamen wieder. Dieses lässt sich in vielen Grafikprogrammen problemlos importieren und weiter bearbeiten. Das PDF liegt auf der Festplatte im gleichen Verzeichnis wie der Code des Programms selbst; ein Klick auf Sketch/Zeige Sketch Verzeichnis bringt es zum Vorschein.

Das Beispielprogramm Stern_2 exportiert ein PDF ...
... dessen starke Vergrößerung zeigt, dass Processing dabei echte Vektorgrafiken erzeugt.

Schleifenlos glücklich

Bisher listen die vorgestellten Programmskizzen Anweisung um Anweisung auf, die Processing genau in der vorgegebenen Reihenfolge abarbeitet und zum Schluss als fertiges Bild auf den Schirm zeichnet.

Möchte man dem Computer lieber Schritt für Schritt zusehen, unterteilt man sein Programm in zwei Blöcke. Alles, was die geschweifte Klammer nach void setup() umfasst, führt der Interpreter nach Start des Programms genau einmal aus. Die Anweisungen, die auf void draw() folgen, werden immer wieder ausgeführt und die Darstellung des Programmfensters aufgefrischt, bis das Programm beendet wird – als ob sie in einer endlos laufenden Schleife stünden.

Bei setup() und draw() handelt es sich um Standard-Funktionen von Java-Applets, die man in Processing mit eigenem Leben füllen kann. Funktionen sind so etwas wie selbst definierte Befehle. Ruft man sie auf, muss man ihnen die Parameter mitgeben, die in der runden Klammer angegeben sind – ist die Klammer leer, erwartet die Funktion keine Parameter. Das Schlüsselwort void gibt an, dass die Funktion am Ende kein Ergebnis zurückliefert. Ansonsten wäre dessen Typ angegeben, etwa int für eine ganze oder float für eine Gleitkommazahl.

Einfache Abfragen für die Position des Mauszeigers bringen Interaktion in Kunstprogramme.

Definiert man Variablen ganz zu Anfang des Programms, außerhalb jeder geschweiften Klammer, kann man auf sie von allen Funktionen aus zugreifen – ansonsten sind sie nur innerhalb der Funktion bekannt, in der sie definiert werden. Das Programm Stern_3 listet eine ganze Reihe Variablen auf, ehe setup() Größe und Hintergrundfarbe des Programmfensters festlegt. Jeder Durchgang von draw() fügt dem Bild einen Stahl des Sterns hinzu. Strichstärke und Farbe des Strahls sind zufällig, die maximale Länge hängt direkt von der Stärke ab. Die Strahlen entspringen bei diesem Programm allerdings nicht in der Mitte des Programmfensters, sondern an der Position des Mauszeigers, für die man einfach die Variablen mouseX und mouseY einsetzt:

line (mouseX, mouseY, mouseX+dx, mouseY-dy);

Trotzdem soll zunächst ein Stern von der Mitte aus beginnen, weshalb setup() den Mauszeiger zu Beginn in die Mitte des Fensters setzt:

mouseX = width/2;
mouseY = height/2;

Bis es beendet wird, schickt das Programm immer neue Strahlen los. Dank einer weiteren Standardfunktion lässt sich aber ein Zwischenzustand als Pixelbild speichern:

void mousePressed(){
save("Stern.png");
}

Wird eine Maustaste gedrückt, ruft Processing diese Funktion außer der Reihe auf. Der Screenshot landet wieder im gleichen Verzeichnis wie der Code. Drückt man mehrmals, wird die ältere Bilddatei allerdings rücksichtslos übergebügelt.

Stern_4 variiert seinen Vorgänger: Am Anfang von draw() legt das Programm übers gesamte Fenster ein nahezu transparentes Rechteck in der Hintergrundfarbe. Ältere Strahlen scheinen dadurch zu verblassen. Der Effekt variiert, wenn man sich an der Deckkraft der Füllfarbe zu schaffen macht.

Spieltrieb

Die folgenden zwei Programme sind deutlich umfangreicher als die bisher besprochenen. Wer sie im Detail verstehen will, muss in den Quellcode schauen und dort die Kommentare lesen – nur die wichtigsten Aspekte können hier zur Sprache kommen.

Solopong ist eine Art Squash für eine Person, das mit der Maus gespielt wird. Intern baut das Programm auf die gleiche Geometrie wie die Stern-Programme auf: So wie dort der Endpunkt eines Strahls aus dessen Richtung und Länge berechnet wurde, ergibt sich bei Solopong die neue Position des Balls aus dessen Flugrichtung und Geschwindigkeit.

Die Anweisung frameRate(30) stellt sicher, dass Processing die Funktion draw() höchstens dreißig Mal pro Sekunde ausführt – damit ist der Ball auch auf schnellen Rechnern noch zu kriegen. Dank Double Buffering bei der Anzeige bringt die Laufzeitumgebung selbst solche Actionspiele flimmerfrei auf den Bildschirm.

Auch für ein kleines Spielchen zwischendrin ist Processing zu haben.

Um die errungene Punktzahl ins Programmfenster schreiben zu können, muss man zuerst einen Font importieren. Der Dialog Tools/Schrift erstellen bietet dazu alle auf dem System installierten Schriftarten an. Das Vorschaufenster zeigt den Font in der gewählten Schriftgröße an. Auswahlboxen legen fest, ob die Buchstaben pixelig oder mit Anti-Aliasing erscheinen sollen, Characters/All Characters holt auch die Umlaute mit ins Boot.

Hinter den Kulissen speichert Processing die Buchstaben der Schrift als Pixel-Texturen in einer Datei, deren Namen dem Muster Schriftname-Größe.vwl folgt. Diese Schrift steckt in einem Unterverzeichnis namens data, das am gleichen Ort abgelegt wird wie die Codedatei. Die Schrift wandert ins Programm über die Zeilen

PFont schrift = loadFont("Georgia-14.vlw");
textFont(schrift);
text("Text", x, y);

Der Text zwischen den Anführungszeichen erscheint anschließend im Programmfenster. Die Grundlinie der Textzeile liegt auf Höhe y, der erste Buchstabe beginnt bei Koordinate x. Die Schriftfarbe gilt unter Processing als Füllung, lässt sich also über fill() festlegen.

Ein Druck auf die Taste "n" ("N" geht auch) startet bei Solopong ein neues Spiel. Im Code passiert die Tastaturabfrage innerhalb von draw() über die Zeilen

if(keyPressed) {
if (key == 'n' || key == 'N') {
newGame();
}

Das doppelte Gleichheitszeichen prüft, ob das an die Taste gebundene Zeichen der Erwartung entspricht. Die beiden senkrechten Striche bedeuten "oder": Ist eine der Bedingungen erfüllt, wirft die Funktion newGame() den nächsten Ball ein.

Verwirrspiel

Das Programm Schiebepuzzle importiert ein Pixelbild, teilt es in 25 Quadrate auf und wirft eines davon weg. Dann mischt es die Bildquadrate gründlich durch: Ein zufällig ausgewähltes Nachbarquadrat schließt die Lücke und reißt eine neue auf, in das der nächste Stein rutscht und so fort. Nach tausend Verschiebe-Aktionen bekommt schließlich der Spieler ein konfuses Puzzle zu Gesicht und kann dann versuchen, anhand einer verkleinerten Abbildung das Bild wieder in Ordnung zu bringen.

Processing kann auch mit Pixelbildern einiges anstellen – beim Schiebepuzzle sägt es einen Makey in handliche Blöcke und bringt diese ordentlich durcheinander.

Wem das Beispielmotiv nicht gefällt, der kann über Sketch/Datei hinzufügen eine andere Bilddatei vom Typ GIF, JPG, TGA oder PNG aus dem eigenen Dateibestand auswählen, muss anschließend allerdings eventuell die Kantenlänge eines Puzzleteils und die Anzahl der Quadrate an die andere Bildgröße anpassen. Eine Kopie des importierten Bilds legt Processing im bereits bekannten Unterverzeichnis data an. Von dort aus lädt man sie ins Programm über die Zeilen

PImage bild;
...
bild = loadImage("Bilddatei.jpg");

Für den Bildtyp PImage stellt Processing eine Reihe nützlicher Funktionen zur Verfügung. So kopiert bild.get(x, y, b, h) einen Teil der Pixel in ein neues PImage. Wie beim Rechteck-Befehl rect() bestimmen auch hier die ersten beiden Parameter x und y die Koordinaten der rechten oberen Ecke, die beiden letzten legen Breite und Höhe des Ausschnitts fest. Mit zwei ineinander geschachtelten for-Schleifen zerhackt Verschiebepuzzle das Ursprungsbild in handliche Quadrate, die es im zweidimensionalen PImage-Array namens bilder unterbringt. Ein Array ist so etwas wie eine Liste, ein zweidimensionales Array funktioniert wie eine Tabelle: Zum Verschieben der Quadrate muss man ab jetzt nur noch mit Zeilen- und Spalten-Indizes hantieren und kann Pixel-Koordinaten komplett vergessen. Anschließend schickt bilder[LEERX][LEERY] = null jenes Bildquadrat ins Nirwana, das an der vorgesehenen Leerstelle hockt.

Zum Schluss von setup() legt der Befehl noLoop() fest, dass draw() nur ein einziges Mal automatisch aufgerufen wird. Anschließend harrt das Programm der Dinge, die da kommen. Für die Rettung vor endloser Langeweile sorgt keyPressed(). Ähnlich wie mousePressed() bei Stern_3 ruft Processing diese Funktion selbstständig auf, sobald der Anwender sich am Eingabegerät zu schaffen macht.

Ein Druck auf die Cursortaste mit dem Pfeil nach unten schließt die Lücke, indem das Programm das darüberliegende Quadrat herunterschiebt, die Cursortaste "nach links" bewegt das Quadrat rechts von der Lücke nach links. Die anderen Cursortasten sind nach dem gleichen Prinzip belegt:

if (key == CODED) {
if (keyCode == UP){
puzzleschritt(1);
...
} else if (key == 'v') {
verwirre();
}

Da den Cursortasten kein Buchstabe zugeordnet ist, identifiziert Processing diese über einen Code, was die zweite Fallunterscheidung nötig macht. Gewöhnliche Tasten wie "v" hingegen prüft man ohne Umschweife direkt auf ihren zugeordneten Buchstaben. Die eigentliche Bewegung der Bildquadrate erledigt die Funktion puzzleschritt(), die eine Zahl zwischen 1 und 4 als Richtungscode erwartet. Auch die Mischfunktion verwirre() greift auf puzzleschritt() zurück, als Parameter dient dabei jeweils eine Zufallszahl. Ist die Tastatureingabe ausreichend gewürdigt worden, weist der Befehl redraw() die Processing-Laufzeitumgebung an, einmal die Funktion draw() aufzurufen. Diese kommt im Schiebepuzzle mit zwei Zeilen aus und bringt über zwei selbst gestrickte Funktionen das Puzzle selbst und danach die Seitenleiste inklusive Spielanleitung und Vorlagenbild auf den Schirm.

Fehlersuche

Solange man keinen echten Mist programmiert, bleibt Processing handzahm. Auf lässliche Sünden wie Schreibfehler bei Variablennamen reagiert der Editor noch höflich und weist unter sanfter Braunfärbung der ansonsten grauen Statusleiste auf mögliche Verwechslungen hin: "No field named 'xy' was found... However, there is an accessible field 'Xy' whose name closely matches the name 'xy'." Die Meldung "Unexpected token xyz" oder die Frage, ob womöglich eine rechte Klammer fehlt, weist häufig eher auf ein deplatziertes oder fehlendes Semikolon hin. (Manchmal fehlt aber auch wirklich eine Klammer.) Tut man hingegen richtig Verbotenes, wirft Processing dem freigeistigen Kreativ-Hacker im schwarzen Stockwerk unter der Statusleiste haufenweise Java-Fehlermeldungen in blutroter Schrift entgegen. Aus diesen wird man leider nur mit Routine im Umgang mit Java schlau. Die ganz links unten in der dunkelgrauen Leiste versteckte Zeilennummer erlaubt aber zumindest die Codezeile zu identifizieren, in der der Wurm steckt.

Durch die sparsame Ausstattung mit Werkzeugen für die Fehlerjagd erzieht Processing zum Programmieren in minimalen Schritten. Am besten ändert man immer nur ein Detail und wirft dann schnell einen Probelauf an. Ruft man zwischendrin öfter Bearbeiten/Autoformatierung auf (Tastaturkürzel: Strg+T), fallen fehlende Klammern schnell auf: Lässt sich der Code nicht schulmäßig einrücken, meldet Processing zurück, ob die öffnenden oder schließenden Klammern in der Überzahl sind.

Weite Welt

Processing-Skizzen laufen – dank ihres Java-Kerns – auch außerhalb ihrer angestammten Sandkiste. Datei/Exportieren verpackt alles Notwendige in ausführbare Dateien, jeweils getrennt für Windows, Linux und Mac OS X. Unter Windows kann man auf Wunsch eine Java-Laufzeitumgebung dazupacken.

Unsere Beispiele zeigen nur einige der Talente (und Grenzen) von Processing. Ausreizen können sie die Programmierumgebung längst nicht. Auf der Webseite des Projekts findet man unter dem Menüpunkt Reference/Libraries unter der Überschrift Contributions zusätzliche Bibliotheken von dritter Seite, mit deren Hilfe man seine Processing-Programme etwa mit Sound oder einer Physik-Engine aufmotzen kann.

Egal ob Sie das Software-Skizzenbuch persönlich für Spielereien oder ernsthafte Visualisierung einsetzen, ob Sie damit kreative Filter für Ihre Digitalfotos programmieren oder den Computer abstrakte Vektoranimationen berechnen lassen – wir freuen uns über jede Processing-Skizze von Leserseite, die uns per Mail erreicht.

174 Kommentare