Themen
p5
- Ausgabe des aktuellen Datums
- Bilder speichern
- Events in p5
- kontinuierliche Animation
- Zufall
- if/else Bedingungen
- …
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…
In p5 erzeugte Bilder lassen sich in verschiedenen Formaten speichern und dann in anderen Programmen weiterverarbeiten!
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");
}
Je nach Browser wird das Bild direkt bei Downloads abgespeichert oder es springt ein Dialogfenster auf und fragt…
Hier ein paar Beispiele von Events in 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?
}
Die Anweisungen, die sich innerhalb von function draw() befinden, werden immer wieder aufgerufen!
Öffnet den Sketch und ändert die frameRate
// 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;
}
function setup() {
// hier alles einfügen, was am Anfang
// passieren soll
}
function draw(){
// hier die Aufgaben einfügen,
// die das Programm kontinuierlich
// machen soll
}
Während das Programm läuft, wird die X-Koordinate laufend um 6px erhöht – das erzeugt die Animation
Klickt auf den Sketch – damit fängt die Animation wieder von vorne an (siehe mousePressed())!
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;
}
schaut genau, wo Ihr die background-Angabe hinschreibt!
Der Code ist bis auf die Positionierung der Anweisung background() identisch mit dem vorherigen Sketch!
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;
}
Über random() kann man zufällige Zahlen erzeugen…
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…
// 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));
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;
}
Klickt auf den Sketch: Jedesmal wird die frameRate erhöht…
// 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…
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.
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!
function draw() {
if (1. Bedingung) {
// dann soll das passieren
} else {
// ansonsten – wenn obere Bedinung nicht zutrifft
}
}
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.
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!
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!
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…)
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;
}
}
An den Rändern ändert sich die Richtung der Animation
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)
Tip: Mit einem Mouse-Klick startet Ihr die Animation wieder …
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)!
Speichert Euren Sketch im Web-Editor von p5 als 06_uebungen_uhrzeit
Schaut bei den p5-Referenzen nach, wie man Stunde, Minute und Sekunde abfragen kann…
Der Hintergrund des Sketches soll rot (255,0,0) werden, wenn der Durchmesser des Kreises kleiner 250px ist, sonst soll der Hintergrund schwarz bleiben
Speichert Euren Sketch im Web-Editor von p5 als 08_zufaellige_kreise
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.
beim nächsten Treffen (10.12.) sprechen wir noch mal über Eure Hölzchenspiele…