p5, Teil 2 / 2021-12-03 / Matthias Edler-Golla, CC BY-SA 4.0



Themen

p5

  • Ausgabe des aktuellen Datums
  • Bilder speichern
  • Events in p5
  • kontinuierliche Animation
  • Zufall
  • if/else Bedingungen

Ausgabe von Text

Demo

Im Web Editor anzeigen

p5

function setup() {
  createCanvas(960, 100);
  background(255);

  // fill hier für die Textfarbe
  fill(255,0,0);

  // Schriftgröße
  textSize(60);

  textFont("Arial");

  // Datum setzt sich aus Tag, Monat und Jahr zusammen
  let Datum = day() + "." + month() + "." + year();

  // Ausgabe-Text wird zusammengebaut
  let Ausgabe = "Heute ist der " + Datum;

  // Inhalt des Textes, x-Position, y-Position
  text(Ausgabe, 10, height-20);
}

day(), month(), year() sind „System-Variablen“, die das Datum abfragen, die auf dem jeweiligen Computer eingestellt sind…


Bilder speichern

In p5 erzeugte Bilder lassen sich in verschiedenen Formaten speichern und dann in anderen Programmen weiterverarbeiten!

Demo

Im Web Editor anzeigen

p5

function setup() {
  createCanvas(960, 600);
  background(255);

  let r = 5; // Radius des Kreises
  let a = (2*r) + 1; // Abstand = 2 * Radius + 1px;

  fill(0);
  noStroke();
  ellipseMode(RADIUS);

  // Loop aus letztem Script…
  for (var y = a; y < height - a; y = y + a) {
    for (var x = a; x < width - a; x = x + a) {
      fill(255-y/2,0+y/2,0+y/2);
      ellipse(x, y, r, r);
    }
  }

  // damit wird das Bild "muster.png" erzeugt
  // es ist auch das Format ".jpg" möglich
  save("muster.png");
}

Ablage des Bilder

Je nach Browser wird das Bild direkt bei Downloads abgespeichert oder es springt ein Dialogfenster auf und fragt…


Events in p5

Demo

Im Web Editor anzeigen

Event = Ereignisse

Hier ein paar Beispiele von Events in P5

p5

function setup(){
  // Einstellungen beim Starten des Programmes
}

function draw(){
  // was passiert, während das Programm läuft?
}

function mousePressed(){
  // was passiert, wenn der User die MouseTaste drückt?
}

function mouseReleased(){
  // was passiert, wenn der User die MouseTaste wieder loslässt?
}

function keyPressed(){
  // was passiert, wenn der User eine Taste auf dem Keyboard drückt?
}

function draw(): Ein sich wiederholender Event

Die Anweisungen, die sich innerhalb von function draw() befinden, werden immer wieder aufgerufen!

Demo

Im Web Editor anzeigen

Öffnet den Sketch und ändert die frameRate

p5

// Zahl, die sich jedesmal um 1 erhöht
// wenn draw aufgerufen wird
let a = 0;

function setup() {
  createCanvas(960, 200);
  background(255);

  // eine Wiederholung pro Sekunde
  frameRate(1);

  fill(0);
  textSize(260);
  textAlign(CENTER);
}

// dies läuft immer wieder ab
// abhängig von der "frameRate) dauert dies unterschiedlich lang
function draw(){
  background(255);
  text(a, width/2, height-10);

  // a wird jeweils um 1 erhöht
  a = a + 1;
}

p5

function setup() {
  // hier alles einfügen, was am Anfang 
  // passieren soll
}

function draw(){
  // hier die Aufgaben einfügen, 
  // die das Programm kontinuierlich
  // machen soll
}

kontinuierliche Animationen

Während das Programm läuft, wird die X-Koordinate laufend um 6px erhöht – das erzeugt die Animation

Demo

Im Web Editor anzeigen

Klickt auf den Sketch – damit fängt die Animation wieder von vorne an (siehe mousePressed())!

p5

let x = 0; // X-Wert des Punktes
let d = 80; // Durchmesser des Punktes

function setup() {
  createCanvas(960, 200);
  noStroke();
  frameRate(30); // 30 Bilder pro Sekunde
}

// dies läuft immer wieder ab
// abhängig von der "frameRate) dauert dies unterschiedlich lang
function draw(){
  background(255);
  fill(255,0,0);

  ellipse(x, height/2, d, d);

  // hiermit bewegt sich der waagrecht
  // umso größer die Zahl ist, desto schneller (und ruckliger)
  // bewegt sich der Kreis!
  x = x + 6;
}

// Damit fängt die Animation wieder von vorne an
function mousePressed(){
  background(255);
  x = 0;
}

Kleiner, aber wichtiger Unterschied

schaut genau, wo Ihr die background-Angabe hinschreibt!

Demo

Im Web Editor anzeigen

Der Code ist bis auf die Positionierung der Anweisung background() identisch mit dem vorherigen Sketch!

p5

let x = 0; // X-Wert des Punktes
let d = 80; // Durchmesser des Punktes

function setup() {
  createCanvas(960, 200);

  // Hintergrund wird *NUR* beim Starten des Sketches gezeichnet
  background(255);

  noStroke();
  frameRate(30); // 30 Bilder pro Sekunde
}

// dies läuft immer wieder ab
// abhängig von der "frameRate) dauert dies unterschiedlich lang
function draw(){

  // hier fehlt die Angabe zum Background!

  fill(255,0,0);

  ellipse(x, height/2, d, d);

  // hiermit bewegt sich der waagrecht
  // umso größer die Zahl ist, desto schneller (und ruckliger)
  // bewegt sich der Kreis!
  x = x + 6;
}

// Damit fängt die Animation wieder von vorne an
function mousePressed(){
  background(255);
  x = 0;
}

Zufall

Über random() kann man zufällige Zahlen erzeugen…

Demo

Im Web Editor anzeigen

p5

function setup() {
  createCanvas(960, 100);
  textAlign(CENTER);
  textSize(120);
  frameRate(1); // 1 Bild pro Sekunde
}

function draw(){
  // Zufallswert zwischen 0 und 120
  // "int()" sorgt dafür, dass nur ganze Zahlen angegeben werden
  let zahl = int(random(0, 120));

  // Hintergrund wird entsprechend der Zufallsfarbe dargestellt
  // kann also zwischen 0 und 120 liegen
  background(zahl);

  fill(255);

  // Ausgabe des Wertes "t"
  text(zahl, width/2, height-8);
}

Der Bereich und die Genauigkeit der Zufallszahl kann man einstellen…

p5

// gibt zufällig Zahlen zwischen 0 und 19,999… aus;
random(20);

// gibt zufällig Zahlen zwischen -5 und 999,999…;
random(-5, 1000);

// will man nur ganze Zahlen (keine Kommastellen), 
// muss man ein "int()" davorschalten
// hier werden nur ganze Zahlen von 0 bis 255 erzeugt
int(random(0, 255));

Animation mit Zufall

Demo

Im Web Editor anzeigen

p5

let x = 0; // X-Wert des Punktes
let d = 80; // Durchmesser des Punktes

function setup() {
  createCanvas(960, 200);
  background(255);
  noStroke();
  frameRate(30); // 30 Bilder pro Sekunde
}

// dies läuft immer wieder ab
// abhängig von der "frameRate) dauert dies unterschiedlich lang
function draw(){
  background(255);

  // Zufallswert zwischen -40 und 40
  // nur ganze Zahlen durch "int()"
  let z = int(random(-40,40));
  textSize(18);
  textFont("Verdana");
  fill(190);
  text("Zufallszahl: " + z, 10, height-20);

  fill(255,0,0);

  // Position des Kreises, hier mit Zufallswert
  ellipse(x, height/2 + z, d, d);

  // hiermit bewegt sich der waagrecht
  // ebenfalls mit Zufallswert
  x = x + 6 + z;
}

// Damit fängt die Animation wieder von vorne an
function mousePressed(){
  background(255);
  x = 0;
}

Zufällige Linien

Demo

Im Web Editor anzeigen

Klickt auf den Sketch: Jedesmal wird die frameRate erhöht…

p5

// um den Wert "a" schwanken die x-Werte der Linien
// und erzeugen so eine zufällige Positionierung
let a = 15;

let fr = 5; // die Framerate

function setup() {
  createCanvas(960, 300);
  frameRate(fr);
}

// dies läuft immer wieder ab
// abhängig von der "frameRate) dauert dies unterschiedlich lang
function draw(){
  background(0);

  // for-loop, der ganze Breite des Sketches berücksichtigt
  for (x = a; x < width -a; x = x + a) {

    //rgb-Werte von 50 bis 255; durch "int" immer ganze Zahlen
    stroke(int(random(50,255)),int(random(50,255)),int(random(50,255)));

    // Strichstärke zwischen 3 und 10
    strokeWeight(random(3,10));

    // linie, die zufällig etwas "schwankt"
    line(x + random(-a, a), 10, x + random(-a, a), height-10);
  }
}

// bei MouseClicken wird die Framerate erhöht
function mousePressed(){
  fr = fr + 5;
  frameRate(fr);
}

Überlegt mal, wie der Sketch-Code aussehen müsste, dass Ihr bei mousePressed() ein PNG generiert – weil Euch z.B. das entstandene Muster so gut gefällt…


Bedingungen (1)

Demo

Im Web Editor anzeigen

Pseudocode

Wenn sich der Cursor in der linken Hälfte des Sketches befindet, soll eine rote Hintergrundfarbe verwendet werden. Ansonsten soll der Sketch einen blauen Hintergrund haben.

p5

function setup() {
  createCanvas(960, 240);
  textFont("Georgia");
  textSize(30);
  fill(255);
}

function draw(){
  // wenn sich der Cursor in der linken Hälfte
  if (mouseX < width/2) {
    background(255, 0, 0);
    textAlign(LEFT);
    text("Cursor in linker Hälfte", 10, height-40, width-10, 60);
  }
  // ansonsten; hier muss man gar nicht die rechte Hälfte angeben
  else {
    background(0, 0, 255);
    textAlign(RIGHT);
    text("Cursor in rechter Hälfte", 10, height-40, width-20, 60);
  }

  // Strich in der Mitte des Sketches
  stroke(0);
  line(width/2, 0, width/2, height);
}

Achtet darauf, dass Ihr bei if/then keine Klammern vergesst – dann funktioniert es nicht!

p5

function draw() {

  if (1. Bedingung) {
    // dann soll das passieren
  } else {
    // ansonsten – wenn obere Bedinung nicht zutrifft
  }

}

Bedingungen (2)

Demo

Im Web Editor anzeigen

Pseudocode

Wenn sich der Cursor im 1. Drittel des Sketches befindet, soll eine rote Hintergrundfarbe verwendet werden. Im 2. Drittel soll der Hintergrund blau werden, ansonsten soll der Sketch einen grünen Hintergrund haben.

p5

function setup() {
  createCanvas(960, 240);
  textFont("Georgia");
  textSize(30);
  fill(255);
  stroke(0);
}

function draw(){
  if (mouseX < width/3) { // Cursor im linken Drittel
    background(255, 0, 0);
    text("1. Drittel", 10, height-40, width-10, 60);
  } else if (mouseX < (width/3)*2) { // Cursor im mittleren Drittel
    background(0, 0, 255);
    text("2. Drittel", width/3 + 10, height-40, width/3, 60);
  } else { // Cursor im rechten Drittel; muss hier nicht explizit angegeben werden (kann man aber…)
    background(0, 255, 0);
    text("3. Drittel", (width/3)*2 + 10, height-40, width/3, 60);
  }

  // Strich beim 1. Drittel des Sketches
  line(width/3, 0, width/3, height);

  // Strich beim 2. Drittel des Sketches
  line((width/3)*2, 0, (width/3)*2, height);
}

Achtet darauf, dass Ihr bei if/then keine Klammern vergesst – sonst funktioniert es nicht!

p5

function draw() {

  if (1. Bedingung) {
    // dann soll das passieren
  } else if (2. Bedingung) {
    // dann soll das passieren
  } else {
    // ansonsten – wenn beide oberen Bedinungen nicht zutreffen
  }

}

Ihr könnt beliebig viele else if einbauen und somit sehr viele Bedingungen abfragen!

Wenn es sehr viele unterschiedliche Bedingungen gibt, ist switch() übersichtlicher – schaut Euch dies mal an!


Pacman läuft im Kreis

Demo

Im Web Editor anzeigen

Wenn man weiss, wo sich Pacman befindet, kann man diesen „im Kreis laufen“ lassen (d.h. hier, dass man ihn wieder an den linken Rand des Sketches zurückversetzt…)

p5

let x = 0; // waagrechte Anfangsposition von Pacman
let r = 80; // Radius von Pacman

function setup() {
  createCanvas(960, 150);
  noStroke();
  fill(255, 0, 0);
  frameRate(30);
}

function draw() {
  background(0);

  // durch random() bewegt Pacman seinen Mund…
  // m = die Öffnung des Mundes
  let m = random(-10, 10);

  // radians(30) = 30° nach unten von der horizontalen Linie
  // radians(-30) = 30° nach oben von der horizontalen Linie

  arc(x, height / 2, r, r, radians(30 + m), radians(-30 - m));

  if (x < width) {
    // solange sich Pacman innerhalb der Sketch-Fläche befindet
    // wird er waagrecht animiert
    x = x + 8;
  } else {
    // ansonsten wird er wieder nach links versetzt
    x = -30;
  }
}

Kreis läuft hin und her

Demo

Im Web Editor anzeigen

An den Rändern ändert sich die Richtung der Animation

p5

let x = 40; // Anfangsposition des Kreises
let  r = x; // Radius des Kreises
let  richtung = 1; // in welche Richtung läuft der Kreis

function setup() {
  createCanvas(960, 150);
  noStroke();
  fill(255, 0, 0);
}

function draw(){
  background(0);

  // Ellipse wird mit Radius-Angaben gezeichnet
  ellipseMode(RADIUS);

  ellipse(x, height/2, r, r);

  // "||" bedeutet "oder"

  // wenn der Kreis am rechten Rand ODER am linken Rand anstößt
  // dreht sich die Richung um

  // damit der Kreis nicht visuell über die Ränder hinausgeht
  // wird jeweils der Radius "r" mitgerechnet
  if ((x > width - r) || (x < 0 + r)) {
    richtung = -richtung; //Richtung kehrt sich um, ist also 1 oder -1;
  }

  // 10 * -1 = -10…
  x = x + (10 * richtung);
}

Richtung kann entweder „1“ oder „-1“ sein – damit wird bei x entweder 10 dazugezählt (Kreis bewegt sich nach rechts) oder abgezogen (Kreis bewegt sich nach links)


Schwerkraft und Dämpfung

Demo

Im Web Editor anzeigen

Tip: Mit einem Mouse-Klick startet Ihr die Animation wieder …

p5

let diam = 40;
let r = diam / 2;

// Startposition
let x = 400;
let y = 0 + r;

let speed = 0;
let gravity = 0.3;

// Dämpfung
let d = -0.94;

function setup() {
  createCanvas(960, 500);
  noStroke();
  fill(255, 0, 0);
  frameRate(60);
}

function draw() {
  background(230);

  ellipse(x, y, diam, diam);

  // Ball fällt immer schneller runter
  y = y + speed;
  speed = speed + gravity;
  // console.log(speed);

  // wenn der Ball den untern Rand berührt,
  // dreht sich die Richtung um und die Bewegung wird gebremst
  if (y > height - r + 10) {
    speed = speed * d;
  }
}

function mousePressed() {
  x = random(100, width - 20);
  y = 0 + r;
}

Spielt mit den Werten für „gravity“ und „d“ (Dämpfung)!


Übungen


Uhrzeit anzeigen

Briefing

  1. Sketchgröße: 960 x 200px
  2. Hintergrundfarbe jede Sekunde zufällig neu
  3. digitale Uhrzeitdarstellung (z.B. 14:45:30)
  4. Uhrzeit soll sich jede Sekunde aktualisieren

Speichern

Speichert Euren Sketch im Web-Editor von p5 als 06_uebungen_uhrzeit

Tip:

Schaut bei den p5-Referenzen nach, wie man Stunde, Minute und Sekunde abfragen kann…


Kreis animieren

Briefing

  1. Größe des Sketch: 960 x 400px, schwarzer Hintergrund
  2. Größe des Kreises: 40px Durchmesser
  3. Kreis bewegt sich diagonal von der linken, oberen Kante nach unten
  4. Ist er am unteren Rand angekommen, fängt er links oben wieder an

Zufällige Kreise

Briefing

  1. Größe des Sketch: 960 x 400px, schwarzer Hintergrund
  2. 10 Bilder pro Sekunde
  3. Größe des Kreises am Anfang: 250px Durchmesser
  4. Füllfarbe zufällig in RGB
  5. Durchmesser des Kreises „schwankt“ um 40px: 40px kleiner und 40px größer als 250px

Freiwillige „Königsaufgabe“

Der Hintergrund des Sketches soll rot (255,0,0) werden, wenn der Durchmesser des Kreises kleiner 250px ist, sonst soll der Hintergrund schwarz bleiben

Speichern

Speichert Euren Sketch im Web-Editor von p5 als 08_zufaellige_kreise


Dan Shiffmann Videos


Zeitdarstellung in p5.js

Von Maahmaah: persian tools - Eigenes Werk by zeebad&maahmaah [1], CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=17883105

Zwischenpräsentation Eurer Entwürfe (Illustrator, Photoshop, Skizzen…) beim Treffen am 17.12.

  • Wie soll die Uhrzeit dargestellt werden – analog oder digital?
  • Welche Werte (Stunden, Minuten, Sekunden, Tag, Monat, Jahr…) sollen ablesbar sein?
  • Gibt es eine 12-Stunden Anzeige oder eine 24-Stunden-Anzeige?
  • Gibt es eine andere Darstellung als eine kreisförmige?
  • Wie genau muss man die Uhrzeit ablesen können – reicht es vielleicht auch, dass man nur ungefähr weiss, wie spät es ist?

Präsentation via Zoom und Bildschirmteilen

  • Pro Student:in ca. 2min
  • Idealerweise mehrere Uhrzeiten darstellen, damit wir als Betrachter verstehen können, wie die Zeit abgelesen werden kann

Hölzchenspiel

beim nächsten Treffen (10.12.) sprechen wir noch mal über Eure Hölzchenspiele


Danke

Alle Scripte durchsuchen

Weitere Vorträge: