In diesem Tutorial lernst du, wie du mit Variablen Animationen erstellst. Du wirst eine animierte Landschaft bauen mit bewegten Wolken, wachsenden Bäumen und zufälligen Sternschnuppen!
- Variablen deklarieren und verwenden
- Animation mit
frameCount erstellen
- Bedingte Anweisungen mit
if nutzen
Bisher hatten alle Objekte meistens feste Werte:
function setup() {
createCanvas(600, 400);
}
function draw() {
//gelber Hintergrund
background(255,255,0);
// circle(x, y, radius)
circle(300, 200, 100);
}
Im Folgenden wollen wir vier veränderliche Größen kennenlernen, sogenannte Variablen, mit denen man auch die Position, die Farbe oder die Größe von Objekten ändern kann:
mouseX - die x-Position des Mauszeigers
mouseY - die y-Position des Mauszeigers
key - der Name der zuletzt gedrückten Taste
keyIsPressed - zeigt an, ob eine Taste gedrückt ist
frameCount - die Anzahl der Frames, die bereits abgelaufen sind
Lassen wir uns diese Werte einmal ausgeben:
function setup() {
createCanvas(600, 400);
}
function draw() {
background(220); // hellgrauer Hintergrund
textSize(20); // Schriftgröße 20
text("mouseX: " + mouseX, 10, 20); // Text mit dem mouseX-Wert
text("mouseY: " + mouseY, 10, 40); // Text mit dem mouseY-Wert
text("key: " + key, 10, 60); // Text mit dem key-Wert
text("keyIsPressed: " + keyIsPressed, 10, 80); // Text mit dem keyIsPressed-Wert
text("frameCount: " + frameCount, 10, 100); // Text mit dem frameCount-Wert
}
1. Interaktivität durch mouseX und mouseY
In dem folgenden Beispiel kann man mit dem Mauszeiger zeichnen:
function setup() {
createCanvas(600, 400);
//einmalig den Hintergrund schwarz setzen
background(0); // Kurzform für background(0,0,0)
}
function draw() {
//einen kleinen weißen Punkt an der Mausposition zeichnen
fill("white");
noStroke(); // kein Rand zeichnen
// ACHTUNG: Jetzt nutzen wir die Variablen mouseX und mouseY,
// um einen Punkt an der Mausposition zu zeichnen.
circle(mouseX, mouseY, 10);
}
- Modifiziere den obigen Kreis so, dass er sich mit der Maus bewegt (vielleicht sogar entgegengesetzt) und dabei seine Größe ändert.
- Wie kann man die Bewegung des Kreises verlangsamen oder beschleunigen?
2. Interaktivität durch frameCount
Alles was in draw() steht, wird 60 mal pro Sekunde wiederholt, um Animationen zu ermöglichen: Wie in einem Daumenkino werden Bilder nacheinander gezeigt, um ein Gefühl von Bewegung zu erzeugen:
Die Seitenzahlen in diesem Daumenkino entspricht der Variable frameCount.
Möchte man die Animation beschleunigen oder verlangsamen, kann man die Variable frameRate() verwenden, z.B. ist frameRate(30) die halbe Geschwindigkeit von frameRate(60), denn hier werden nur noch 30 Bilder pro Sekunde gezeigt.
Es hindert uns nichts daran, die Variable frameCount als x-Koordinate ellipse(x,y,breite,höhe) zu verwenden, um eine bewegte Wolke zu zeichnen:
function setup() {
createCanvas(600, 400);
}
function draw() {
//hellblauer Hintergrund
background("skyblue");
frameRate(30); // die Animation auf 30 Bilder pro Sekunde setzen
//bewegte Wolke
fill(255); // weiße Füllung, Kurzform für fill(255,255,255)
noStroke(); // kein Rand zeichnen
ellipse(frameCount, 100,70, 40); // ellipse(x, y, breite, höhe)
// Text, der den frameCount-Wert anzeigt
fill("black");
text("frameCount: " + frameCount, 10, 20);
}
Die Wolke sein nun ein Ufo. Schaffst Du es, dass es:
- nach unten fliegt,
- von rechts nach links fliegt,
- von unten nach oben fliegt,
- von links unten nach rechts oben fliegt?
Verändere auch die Variable frameRate() um die Geschwindigkeit der Animation zu ändern.
Man kann auch eigene Variablen erstellen, die ihre Werte über die Zeit ändern können. Dazu gibt es in p5.js den Befehl let.
// Eigene Variable für die x-Position der Wolke festlegen (deklarieren)
let wolkeX; // die Variable wolkeX festlegen (deklarieren)
function setup() {
createCanvas(600, 400);
// den Wert der Variable wolkeX auf 100 setzen
wolkeX = 100;
}
function draw() {
// himmelblauer Hintergrund
background("skyblue");
// weiße Wolke an der Position wolkeX zeichnen
fill("white");
noStroke(); // kein Rand zeichnen
ellipse(wolkeX,100,70,40); // ellipse(x, y, breite, höhe)
}
Man unterscheidet zwischen dem Erstellen einer Variablen (Deklaration) und dem erstmaligen Zuweisen eines Wertes (Initialisierung):
let wolkeX; - Deklaration der Variablen wolkeX
wolkeX = 100; - Initialisierung der Variablen wolkeX mit dem Wert 100 (meistens in setup())
let wolkeX = 100; - gleichzeitige Deklaration und Initialisierung der Variablen wolkeX mit dem Wert 100
- Verändere den Wert von
wolkeX und beobachte die Veränderung.
- Erstelle eine weitere Variable für die y-Position der Wolke und verwende sie um die Wolke an einer anderen Position zu zeichnen.
- Erstelle eine Variable für die Farbe der Wolke und verwende sie um die Wolke in einer anderen Farbe zu zeichnen.
Variablen verändern
Der Hauptvorteil von Variablen ist, dass man ihre Werte über die Zeit ändern kann.
// Eigene Variable für die x-Position der Wolke festlegen (deklarieren)
let wolkeX;
function setup() {
createCanvas(600, 400);
wolkeX = 100; // den Wert der Variable wolkeX auf 100 setzen (initialisieren)
}
function draw() {
// himmelblauer Hintergrund
background("skyblue");
// neue wolkeX ist gleich alte wolkeX plus 1
wolkeX = wolkeX + 1;
// weiße Wolke an der Position wolkeX zeichnen
fill("white");
noStroke(); // kein Rand zeichnen
ellipse(wolkeX, 100, 70, 40); // ellipse(x, y, breite, höhe)
// Text, der den wolkeX-Wert anzeigt
fill("black");
text("wolkeX: " + wolkeX, 10, 20);
}
Welchen Wert hat die Variable Ergebnis am Ende?
let Ergebnis;
let x = 10;
let y = 20;
y = x+y;
x = y+x;
Ergebnis = x+y;
Bisher hatten wir das Problem, dass manchmal die Werte einer Variable unmögliche Werte annehmen. Dies kann man durch sogenannte bedingte Anweisungen vermeiden. Dazu gibt es in p5.js den Befehl if.
if (wolkeX > 600) { // wenn wolkeX größer als 600 ist,
wolkeX = 0; // dann setze wolkeX (wieder) auf 0
}
Alle Anweisungen in den geschweiften Klammern werden nur ausgeführt, wenn die Bedingung erfüllt ist.
In unserem Beispiel hat dies die folgende Wirkung:
// Eigene Variable für die x-Position der Wolke festlegen (deklarieren)
let wolkeX; // die Variable wolkeX festlegen (deklarieren)
function setup() {
createCanvas(600, 400);
wolkeX = 100;// den Wert der Variable wolkeX auf 100 setzen (initialisieren)
}
function draw() {
// himmelblauer Hintergrund
background("skyblue");
// neue wolkeX ist gleich alte wolkeX plus 1
wolkeX = wolkeX + 1;
// eine bedingte Anweisung setzen:
if (wolkeX > 600) { // wenn wolkeX größer als 600 ist,
wolkeX = 0; // dann setze wolkeX (wieder) auf 0
}
// weiße Wolke an der Position wolkeX zeichnen
fill("white");
noStroke(); // kein Rand zeichnen
ellipse(wolkeX,100,70,40); // ellipse(x, y, breite, höhe)
// Text, der den wolkeX-Wert anzeigt
fill("black");
text("wolkeX: " + wolkeX, 10, 20);
}
Wenn man eine Bedingung überprüft, muss man meist zwei Werte miteinander vergleichen. Dazu gibt es in p5.js die folgenden Möglichkeiten:
Operatoren zum Vergleichen von Werten:
< - kleiner als
> - größer als
<= - kleiner oder gleich
>= - größer oder gleich
== - gleich
!= - ungleich
Verwechsele nicht den Vergleichsoperator == mit dem Zuweisungsoperator =:
let x; // Variable x deklarieren
x = 10; // setzt den Wert der Variable x auf 10
x == 11; // prüft, ob x gleich 11 ist -> dies ist falsch
Den Vergleichsoperator == kann man auch gut bei Tastatureingaben verwenden:
function setup() {
createCanvas(600, 400);
background("gray")
}
function draw() {
// Farbe des Hintergrunds ändern
if (key == 'r') {
background("red");
}
if (key == 'g') {
background("green");
}
// Text, der den Tastenamen anzeigt
fill("black");
text("key: " + key, 10, 20);
}
- Füge noch weitere Farbmöglichkeiten hinzu.
- Lasse auf Tastendruck "k" einen Kreis zeichnen.
- Steuere mit der Tasteneingabe (z.B. "w", "a", "s", "d") eine Emoji-Figur in einem Quadrat.
Man kann auch Zufallswerte erstellen, die sich über die Zeit ändern. Dazu gibt es in p5.js den Befehl random().
WolkeX = random(0, 600); // setzt die x-Position der Wolke auf einen zufälligen Wert zwischen 0 und 600
Aber auch die Farbe des Hintergrunds kann zufällig sein:
let farbe; // deklariere die Variable farbe
let kreisX; // deklariere die Variable kreisX
let kreisY; // deklariere die Variable kreisY
function setup() {
createCanvas(600, 400);
background(0); // Hintergrund schwarz setzen (nur einmalig)
}
function draw() {
// Zufällige Werte (bei jedem Durchlauf der draw()-Funktion)
kreisX = random(0, 600); // Zahl zwischen 0 und 600
kreisY = random(0, 400); // Zahl zwischen 0 und 400
farbe = color(random(0, 255), random(0, 255), random(0, 255)); // Zufällige Farbe
// Kreis zeichnen
fill(farbe); // Farbe des Kreises setzen
noStroke(); // kein Rand zeichnen
circle(kreisX, kreisY, 10); // Kreis zeichnen (x, y, radius)
}
Um alle Themen zusammenzuführen und Ideen für eigene Projekte zu bekommen, folgen nun verschiedene Beispiele.
Beispiel 1 - Animierte Landschaft
// Variable für die x-Position der Wolke
let wolkeX = 0;
// Variablen für die Sternschnuppe
let sternschnuppeX = 0;
let sternschnuppeY = 0;
// Variablen für das Wachstum der Bäume
let baumLinksWachstum = 0;
let baumRechtsWachstum = 0;
function setup() {
createCanvas(400, 400);
}
function draw() {
background('navy');
frameRate(15);
// Sternschnuppe zeichnen
stroke("yellow");
line(sternschnuppeX, sternschnuppeY, sternschnuppeX + 30, sternschnuppeY - 30);
// Mond zeichnen
fill(255);
stroke(0);
circle(350, 50, 100);
stroke("navy");
fill("navy");
circle(320, 50, 100);
// Große graue Berge
stroke(0);
fill(80);
triangle(-40, 300, 75, 100, 250, 300);
triangle(100, 300, 300, 100, 500, 300);
// Gras
fill('rgb(50,76,50)');
rect(0, 300, 400, 100);
// Wolken zeichnen
fill(255);
ellipse(wolkeX, 50, 80, 40);
ellipse(wolkeX - 40, 100, 60, 20);
ellipse(wolkeX + 20, 150, 40, 10);
// Baumstamm links
fill("rgb(118,80,72)");
rect(40, 270, 15, 50);
// Blätter links
fill("green");
triangle(25, 270, 45, 240 - baumLinksWachstum, 70, 270);
// Baumstamm rechts
fill("rgb(118,80,72)");
rect(340, 330, 15, 50);
// Blätter rechts
fill("green");
triangle(325, 330, 345, 240 - baumRechtsWachstum, 370, 330);
// Wolke bewegen: erhöhen und bei Erreichen der Breite zurücksetzen
wolkeX = wolkeX + 1;
if (wolkeX > 400) {
wolkeX = 0;
}
// Baumwachstum links: erhöhen und bei 2900 zurücksetzen
baumLinksWachstum = baumLinksWachstum + 1;
if (baumLinksWachstum >= 2900) {
baumLinksWachstum = 0;
}
// Baumwachstum rechts: erhöhen und bei 290 zurücksetzen
baumRechtsWachstum = baumRechtsWachstum + 1;
if (baumRechtsWachstum >= 290) {
baumRechtsWachstum = 0;
}
// Sternschnuppe an zufällige Position setzen
sternschnuppeX = random(0, 400);
sternschnuppeY = random(0, 400 / 2);
}
Beispiel 2 - Interaktives Zeichenprogramm
let pinselFarbe;
function setup() {
createCanvas(600, 400);
background("lightgray");
pinselFarbe = "black";
}
function draw() {
// pinselFarben
if (key == 'c') {
background("lightgray"); // Canvas löschen
}
if (key == 'r') {
pinselFarbe = "red";
}
if (key == 'g') {
pinselFarbe = "green";
}
if (key == 'b') {
pinselFarbe = "blue";
}
if (key == 's') {
pinselFarbe = "black";
}
// Nur zeichnen wenn Maus gedrückt ist
if (mouseIsPressed) {
fill(pinselFarbe);
noStroke();
circle(mouseX, mouseY, 20);
}
// Farbpalette anzeigen
fill(0);
text("Aktuelle Farbe:", 10, 20);
fill(pinselFarbe);
rect(110, 8, 20, 15);
fill(0);
text("Tasten: c=löschen, r=rot, g=grün, b=blau, s=schwarz", 10, 390);
}
Beispiel 3 - Einfaches Fangspiel
let spielerX, spielerY;
let zielX, zielY;
let punkte = 0;
let geschwindigkeit = 5;
let zielGroesseZuwachs = 0;
function setup() {
createCanvas(600, 400);
spielerX = 300;
spielerY = 200;
// neues Ziel setzen
zielX = random(50, 550);
zielY = random(50, 350);
}
function draw() {
background("darkgray");
// Tastatursteuerung
if (keyIsPressed) {
if (key == 'w') {
spielerY = spielerY - geschwindigkeit;
}
if (key == 's') {
spielerY = spielerY + geschwindigkeit;
}
if (key == 'a') {
spielerX = spielerX - geschwindigkeit;
}
if (key == 'd') {
spielerX = spielerX + geschwindigkeit;
}
}
// Spieler im Canvas halten
if (spielerX < 25) spielerX = 25;
if (spielerX > 575) spielerX = 575;
if (spielerY < 25) spielerY = 25;
if (spielerY > 375) spielerY = 375;
// Ziel zeichnen (grün, pulsierend)
fill("lightgreen");
noStroke();
let zielGroesse = 20;
zielGroesseZuwachs = zielGroesseZuwachs + 1;
if (zielGroesseZuwachs > 20) {
zielGroesseZuwachs = 0;
}
circle(zielX, zielY, zielGroesse+zielGroesseZuwachs);
// Spieler zeichnen
fill(100, 150, 255);
circle(spielerX, spielerY, 50);
// Kollision prüfen
let abstand = dist(spielerX, spielerY, zielX, zielY);
if (abstand < 35) {
punkte = punkte + 1;
// neues Ziel setzen
zielX = random(50, 550);
zielY = random(50, 350);
}
// Punktestand anzeigen
fill(255);
textSize(20);
text("Punkte: " + punkte, 10, 30);
textSize(12);
text("Steuerung: W/A/S/D", 10, 390);
}
p5.js ist eine freie und quelloffene JavaScript-Bibliothek für kreative Programmierung