Processing eignet sich hervorragend, um Programmieren zu lernen, kann aber etwas sperrig im Einsatz sein. Will man ein Programm in einem beliebigen Browser (Chrome, Firefox, Safari etc.) laufen lassen, verwendet man häufig JavaScript, eine Sprache die alle Browser "verstehen". Zum Glück gibt es eine JavaScript-Variante von Processing, die unter dem Namen p5.js läuft. Der Unterschied von JavaScript-Code und Processing ist gar nicht so groß und wenn Sie das Kapitel durcharbeiten, können Sie sehr schnell interaktive Programme in jedem Browser laufen lassen.
Sie finden die Homepage dieses Projekts unter p5js.org. Der Grund für die "5" ist übrigens, dass die Domain "processing.org" zu Gründungszeiten nicht verfügbar war und man daher auf "proce55ing.org" auswich.
Eine wichtige Ressource für die Sprache JavaScript ist das JavaScript-Kapitel meines Online-Skripts "Grundlagen der Webtechnologien".
Sie können jederzeit JavaScript-Code in Ihrem Browser testen, indem Sie die JavaScript-Konsole öffnen. Zum Beispiel in Chrome unter Anzeigen > Entwickler > JavaScript-Konsole. Probieren Sie also alle Beispiele am besten immer gleich aus.
Weiterer wichtiger Link ist die p5.js Reference mit allen Befehlen in p5.js.
Warum ist eine JavaScript-Variante von Processing interessant? Processing ist ja in Java geschrieben, aber Java ist natürlich eine andere Sprache als JavaScript. JavaScript hat sich in den letzten 10-20 Jahren als die Web-Sprache etabliert und ist praktisch auf jeder Webseite im Einsatz. Genauer gesagt, ist JavaScript vor allem in der Frontend-Programmierung im Einsatz, d.h. dass JavaScript tatsächlich direkt im Browser ausgeführt wird. Der dazugehörige Code ist entweder direkt in die Webseiten eingebettet oder wird als Datei von der Webseite nachgeladen.
Warum also p5.js benutzen?
Es gibt auch eine ältere JavaScript-Variante von Processing namens processing.js. Diese Bibliothek erlaubt es, normalen Processing-Code in Webseiten einzubinden. Tatsächlich nutzt mein Processing-Skript diese alte Bibliothek, die seit 2018 nicht mehr weiterentwickelt wird.
Im Gegensatz zu "processing.js" ist bei "p5.js" die Grundidee, dass man tatsächlich die Programmiersprache wechselt, d.h. dass man in JavaScript programmiert und dabei aber sehr ähnliche Funktionen nutzt wie in Processing.
Wenn Sie gelernt haben, in Processing zu programmieren, müssen Sie sich nur an ein paar Unterschiede gewöhnen.
Schauen Sie sich gern auch die Seite p5.js and Processing an, wo die Unterschiede kurz und übersichtlich dargestellt werden (auf Englisch).
In JavaScript gibt man beim Anlegen neuer Variablen keinen Datentypen an. Intern merkt JS zwar schon, ob man eine Zahl oder einen String in einer Variablen ablegt, aber für die Programmiererin macht das keinen Unterschied. Daher nennt man JavaScript auch eine dynamisch typisierte Sprache.
Bei der Deklaration einer neuen Variable stellt man das Schlüsselwort var voran.
var foo;
foo = 42;
var bar = -1.5;
var message = "hallo";
Die Variablen sind global, d.h. sie sind im gesamten Programm sichtbar.
In JavaScript kann man für Strings sowohl einfache als auch doppelte Anführungszeichen verwenden.
var s1 = "hallo";
var s2 = 'welt';
var s3 = s1 + ' ' + s2;
Sie können die beiden auch kombinieren, wenn Sie Anführungszeichen innerhalb von Strings benötigen:
print('Das ist nicht "perfekt".');
print("Das ist nicht 'perfekt'.");
Tatsächlich ist es in den meisten Fällen egal, welche Art von Anführungszeichen Sie verwenden. Tendenziell würde ich sagen, dass man in der JavaScript-Welt vielleicht etwas mehr zu einfachen Anführungszeichen tendiert. Außerdem können Sie die einfachen Anführungszeichen für sich als Erkennungsmerksmal nutzen, damit Sie dem Code besser ansehen, dass Sie jetzt bei JavaScript sind (und nicht bei Java).
Es ist auch erlaubt, den Typ zu ändern, während das Programm läuft. Das heißt, Sie können die selbe Variable für Zahlen und Strings verwenden.
var misc = 42;
print(misc);
misc = 'Hallo, Welt'; // Erlaubt!
print(misc);
Nur weil etwas erlaubt ist, heißt das natürlich nicht, dass man es auch nutzen muss. Sie sollten allgemein schon darauf achten, dass Ihre Variablen konsistent verwendet werden.
In JavaScript gibt es neben var noch das Schlüsselwort let, um Variablen zu deklarieren:
let x = 100;
print(x);
let a = x * 200;
print(a);
Variablen, die mit let deklariert werden, verhalten sich wie lokale Variablen in Processing, insofern schlagen wir vor, dass Sie var für alle globalen Variablen und let für alle lokalen Variablen verwenden. Die echten Unterschiede zwischen den beiden Verwendungsarten sind noch ein bisschen komplexer, aber diese Empfehlung soll hier erst einmal reichen.
Schleifen funktionieren zwar praktisch genauso wie in Java, aber die Laufvariable wir entsprechend dem Gesagten anders deklariert:
for (let i = 0; i < 3; i++) {
print(i);
}
Wie Sie sehen, benutzen wir hier let, damit die Laufvariable lokal bleibt.
Funktionen werden in JavaScript so definiert, dass Sie mit dem Schlüsselwort function eingeleitet werden. Außerdem finden Sie keine Typenangaben bei den Parametern.
function sayHello(greeting, name) {
print(greeting + ' ' + name);
}
Da bei Funktionen kein Rückgabetyp festgelegt wird, erkennen Sie Funktionen mit Rückgabe lediglich an dem Schlüsselwort return.
function add(a, b) {
return a + b;
}
Funktionen nehmen in JavaScript eine wichtige Rolle ein und haben einige erstaunliche Eigenschaften:
Mehr zu Funktionen finden Sie im JavaScript-Kapitel meines Web-Skripts.
Arrays in JavaScript weisen doch einige Unterschiede zu den Arrays in Processing auf:
Schauen wir uns ein Beispiel an:
var xa = []; // neuen, leeren Array erstellen (Längenangabe nicht nötig)
xa.push(5); // Wert hinzufügen, hat Indexposition 0
xa.push(3); // Wert hinzufügen, hat Indexposition 1
xa.push(22); // Wert hinzufügen, hat Indexposition 2
print(xa[1]); // Zugriff auf zweites Element, gibt Wert 3 aus
Mit der Funktion pop() kann man auch das jeweils letzte Element wieder entfernen.
Man kann Arrays auch mit Werten initialisieren:
var names = ['Harry', 'Sally', 'Mary'];
for (let i = 0; i < names.length; i++) {
print(names[i] + " ");
}
Tatsächlich würde man in JavaScript den obigen Code eher mit Hilfe von forEach und einer anonymen Funktion umsetzen.
var names = ['Harry', 'Sally', 'Mary'];
names.forEach(function(n) {
print(n + ' ');
});
Mehr zu Arrays finden Sie im JavaScript-Kapitel meines Web-Skripts.
Schauen Sie sich auch das folgende P5js-Beispiel "Abprallende Bälle" an:
Animation 4Wir gehen hier davon aus, dass Sie eine Webseite erstellen möchten, in der ein Processing-Programm läuft. Sie sollten ein bisschen HTML verstehen. Wenn nicht, schauen Sie in mein Skript Grundlagen der Webtechnologien. Erstellen Sie ein Verzeichnis mit dem Namen "hello". Erstellen Sie dort zwei Dateien.
Dateien erstellen Sie am besten mit einem Texteditor, der für Code-Eingabe optimiert ist. Ich empfehle Visual Studio Code oder Atom. Beide sind kostenlos nutzbar und werden auch im Profibereich genutzt.
Hier übernehmen Sie folgenden Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello</title>
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js">
</script>
<script src="sketch.js"></script>
</head>
<body>
</body>
</html>
Sie speichern die Datei unter "index.html" ab. Sie sehen im Code auch den Verweis auf die zweite Datei "sketch.js", die im gleichen Verzeichnis liegen sollte.
Hier steht Ihr Processing-Code drin. Als Beispiel schreiben wir "hello" auf die Konsole und zeichnen einen Kreis.
function setup() {
print("hello");
createCanvas(100, 100);
}
function draw() {
background(0);
ellipse(50, 50, 80, 80);
}
Sie schon gesagt, müssen beide Dateien im gleichen Verzeichnis liegen. Sie sehen in dem Beispiel auch, dass Sie die Anweisung createCanvas anstatt size nehmen müssen. Ansonsten deutet nur das Wort function auf den Unterschied zu Processing hin.
Wenn Sie die HTML-Datei in einem Browser öffnen, sollten Sie dies sehen:
Um die Konsolenausgabe zu sehen, müssen Sie in die Entwicklungsansicht wechseln.
Nachdem wir das einfachst mögliche Beispiel gesehen haben, können wir uns ein paar Detailfragen zuwenden.
Wie können wir unseren Sketch - also das Grafikfenster - genau platzieren? Dazu müssen wir in HTML einen Container mit einem ID definieren. Wir nennen den ID 'sketch' (das kann aber auch ein anderer Name sein).
<div id='sketch'></div>
In Sketch steht dann in setup Folgendes:
function setup() {
let canvas = createCanvas(200, 200); // binde Canvas an Variable
canvas.parent('sketch'); // ordne Canvas Container mit ID 'sketch' zu
}
function draw() {
...
}
Programme, die im Browser laufen, können natürlich - wenn Sie z.B. auf einem Tablet laufen - über mehrere Finger bedient werden. Wir verarbeitet man diese Eingabepunkte? Man kann sich das wir mehrere Mauszeiger vorstellen.
Um die Finger-Inputs einzufangen, greifen Sie auf den Array touches zu. Schauen Sie sich auch das Beispielprogramm unten an.
Wie immer lernt man am besten, indem man sich Beispiele ansieht. Wir gehen hier einige Programme durch, die im Skript eingeführt wurden.
Sie finden noch viele weitere Beispiele auf der Seite Examples von p5.js. Dort können Sie sogar interaktiv den Code ändern und neu starten.
Hier zeigen wir mehrere Beispiele, wo Bälle animiert werden. Die Links führen Sie zu Einzelseiten, wo der Code live im Browser ausgeführt wird.
Hier sehen Sie eine einfache Animation, wo der Ball von links nach rechts fliegt und wieder in den Bildschirm eintritt, wenn er rechts hinausfliegt:
Animation 1Hier fliegt ein Ball von links nach rechts und prallt dann von der Wand ab, so dass er zurückfliegt:
Animation 2Hier sehen Sie eine Animation, wo ein Ball in eine zufällige Richtung losfliegt und von den Wänden abprallt:
Animation 3Hier sehen Sie eine Animation mit 10 Bällen, die in zufällige Richtungen fliegen und von den Wänden abprallen:
Animation 4Hier sehen Sie ein Eingabefenster für mehrere Finger, wo die Eingabe lediglich visualisiert wird:
Touch 1
Hier sehen Sie einen rotierenden Balken mit Hilfe von translate und rotate:
Hier sehen Sie drei rotierende Balken. Zwei kleine Balken hängen dabei an einem großen Balken. Das wird mit mit Hilfe von push und pop erreicht. Diese Anweisungen ersetzen pushMatrix/popMatrix von Processing: