Introduzione alla programmazione e a p5.js
Premesse
L’esercitazione ha l’obiettivo di introdurre i concetti di base della programmazione, dalle variabili alle classi, e le peculiarità principali di p5.js rispetto a JavaScript.
Il sito per l’editing online del codice è: P5.js Web Editor.
Non è necessario registrarsi se si vuole solo modificare il codice ed eseguirlo [icona “play” in alto a sinistra] ma è necessario creare un profilo se si vuole salvare lo sketch (come viene chiamato il codice scritto).
La presenza dell’icona ▶ è un invito a eseguire il codice subito dopo la modifica.
01. Funzioni setup() e draw()
- cos’è una funzione
setup()edraw()(chiamate automaticamente da p5.js)- nel setup(): provare a inserire
print("chiamata setup()")▶ - nel draw(): provare ad aggiungere
print("chiamata draw()")▶
- nel setup(): provare a inserire
02. Colori
- nel setup() (senza draw()): solo
background(0)▶ - modalità cromatica predefinita (RGB)
- grigi:
background(128)▶ - colori:
background(180, 204, 230)▶ - grigi semitrasparenti:
background(128, 128)▶ - colori semitrasparenti:
background(180, 204, 230, 128)▶
- grigi:
- uso della modalità cromatica HSL
- inizio setup():
colorMode(HSL)▶ - grigio:
background(50)▶ - colore:
background(210, 50, 80)▶ - trasparenza:
background(210, 50, 80, 0.5)▶
- inizio setup():
Modifiche complessive
03. Dimensioni del canvas
- cambiamento dimensioni area di disegno (canvas)
- nel setup() (prima di colorMode()):
createCanvas(400,300)▶
- nel setup() (prima di colorMode()):
- canvas creato con le dimensioni della finestra di visualizzazione
- uso valori
windowWidthewindowHeight:createCanvas(windowWidth, windowHeight)▶
- uso valori
- adattamento continuo alle dimensioni della finestra di visualizzazione
- intercettazione ridimensionamento finestra:
windowResized() - ridimensionamento del canvas:
resizeCanvas() - canvas adattato al ridimensionamento della finestra:
- verifica funzionamento: dopo resizeCanvas():
background(210, 50, 80)▶
- intercettazione ridimensionamento finestra:
Modifiche complessive
04. Disegno di forme geometriche
- disegno di un cerchio:
circle()- nel draw():
circle(0, 0, 200)▶ - spostamento dall’origine (in alto a sinistra):
circle(50, 50, 200)▶ - cambiamento dimensione:
circle(50, 50, 100)▶
- nel draw():
- riempimento e contorno
- colore di riempimento:
fill() - riempimento azzurro chiaro (prima di circle()):
fill(200, 55, 85)▶ - colore del contorno:
stroke() - contorno bianco (prima di circle()):
stroke(100)▶ - spessore del contorno:
strokeWeight() - spessore di 10 pixel (prima di circle()):
strokeWeight(10)▶ - forzatura spessore di default (1 pixel):
strokeWeight(1)▶
- colore di riempimento:
Modifiche complessive
05. Variabili e parametrizzazione
- memorizzare e utilizzare valori variabili
- definire e inizializzare variabili globali (utilizzabili in ogni parte del codice):
- leggere i valori memorizzati
- nel draw(): usare le variabili nel circle():
circle(x, y, diameter)▶
- nel draw(): usare le variabili nel circle():
- ulteriore cerchio (luce della bolla)
- aggiungere altro
circle(x, y, diameter) - impostare dimensioni proporzionali a cerchio precedente (1/8 del diametro):
circle(x, y, diameter / 8)▶ - ottenere spostamenti proporzionali:
▶
- moltiplicazione anziché divisione, per intuire meglio percentuale (20% anziché 1/5):
let offset = diameter * 0.2▶ - disattivazione contorno (prima del 2° circle()):
noStroke()▶ - riempimento bianco (prima del 2° circle()):
fill(100)▶
- aggiungere altro
Modifiche complessive
06. Animazione
- variazione progressiva dei parametri geometrici
- aggiunta variabile (globale) di incremento della posizione:
let speed = 5 - alla fine del draw(): incremento variabile x:
x = x + speed▶ - incremento variabile y (anziché x):
y = y + speed▶ - decremento variabile y:
y = y - speed▶
- aggiunta variabile (globale) di incremento della posizione:
- animazione anziché accumulazione progressiva di disegni
- spostamento di
background(210, 50, 80)dal setup() all’inizio del draw() ▶
- spostamento di
- partenza dal basso della bolla
- nel setup() (perché height non è disponibile prima):
y = height▶
- nel setup() (perché height non è disponibile prima):
Modifiche complessive
07. Casualità
- la funzione
random() - rendere casuale il valore di
x, fra margine sinistro (0) e margine destro (width)- nel setup() (perché random() non è disponibile prima):
x = random(width)▶
- nel setup() (perché random() non è disponibile prima):
- rendere casuale il diametro, fra 50 pixel e 120
- nel setup():
diameter = random(50, 120)▶
- nel setup():
- rendere casuale la velocità, da 1 pixel al fotogramma a 5 pixel al fotogramma
- nel setup():
speed = random(1, 5)▶
- nel setup():
- dipendenza valori da parametro casuale (
diameter)- spostare inizializzazione di
diametera prima di quella dix - variabile
ydipendente dal raggio (diameter/2):y = height + diameter/2▶ - velocità proporzionale al diametro:
let speed = diameter / 30▶
- spostare inizializzazione di
Modifiche complessive
08. Classi e proprietà
- definire in un’unica entità le variabili e le istruzioni di oggetti simili
- differenza fra classe e istanze
- definire la classe della bolla e le sue proprietà:
- creare la classe:
- definire le proprietà della classe (con il this) e i valori iniziali:
- creare la classe:
- riadattare il codice
- eliminare le variabili globali
x,y,diameterespeed - aggiungere la variabile globale per l’istanza della classe Bubble:
let bubble - nel setup(): creare l’istanza:
bubble = new Bubble() - nel draw(): usare le proprietà del’istanza al posto delle variabili:
x->bubble.xy->bubble.ydiameter->bubble.diameterspeed->bubble.speed▶
- eliminare le variabili globali
Modifiche complessive
09. Metodi delle classi
- aggiunta metodi alla classe
- metodo display() (per disegno della bolla)
- spostamento istruzioni del draw() (tranne background()) nel metodo display()
- nel display(): sostituzione di
bubbleconthis(riferimento a proprietà della classe):bubble.x->this.xbubble.y->this.ybubble.diameter->this.diameterbubble.speed->this.speed
- uso del metodo display()
- nel draw() (dopo background()):
bubble.display()▶
- nel draw() (dopo background()):
Modifiche complessive
10. Array di istanze
- sostituzione istanza singola (
bubble) con array di istanze- sostituzione di
let bubbleconlet bubbles = [](array vuoto)
- sostituzione di
- creazione di due istanze e memorizzazione nell’array
- nel setup(): sostituzione di
bubble = new Bubble()conbubbles[0] = new Bubble() - aggiunta istanza all’array:
bubbles[1] = new Bubble()
- nel setup(): sostituzione di
- uso delle istanze
- nel draw(): sostituzione di
bubble.display()conbubbles[0].display()▶ - aggiunta chiamata metodo seconda istanza:
bubbles[1].display()▶
- nel draw(): sostituzione di
Modifiche complessive
11. Ripetizione di istruzioni
- ripetizione di istruzioni: la struttura di controllo
for - creazione di più istanza e loro memorizzazione e uso
- definire variabile globale con numero di elementi dell’array:
let totalBubbles = 50 - nel setup(): al posto di
bubbles[0] = new Bubble()ebubbles[1] = new Bubble()inserire: - nel draw(): al posto di
bubbles[0].display()ebubbles[0].display()inserire: ▶
- definire variabile globale con numero di elementi dell’array:
Modifiche complessive
12. Istruzioni condizionali
- far eseguire o meno un’istruzione: la struttura di controllo
if - riportare in basso la bolla quando esce dal canvas
- nel metodo display() della classe: aggiungere:
▶
- per la sparizione completa della bolla, sostituire la condizione
this.y < 0conthis.y < this.diameter/2▶
- nel metodo display() della classe: aggiungere:
▶
Modifiche complessive
13. Interattività
- eventi e variabili di sistema (gestiti da p5.js)
- intercettare la pressione del tasto del mouse:
mousePressed()- fuori da ogni altra funzione: aggiunta di un’istanza alla pressione del tasto del mouse:
▶
- fuori da ogni altra funzione: aggiunta di un’istanza alla pressione del tasto del mouse:
▶
- posizionamento istanza sotto il cursore del mouse: le variabili
mouseXemouseY- nel mousePressed(): al posto di
bubbles.push(new Bubble()): ▶
- nel mousePressed(): al posto di
- modifica del cursore del mouse (per suggerire possibilità di interazione)
- nel setup():
cursor("cell")▶
- nel setup():
Modifiche complessive
14. Aggiunta proprietà
- usare una proprietà per limitare la durata dell’istanza (ad esempio:
life)- nel costruttore della classe: aggiungere
this.life = random(100,1000)
- nel costruttore della classe: aggiungere
- ridurre la “vita” dell’istanza a ogni fotogramma
- nel metodo display(): aggiungere
this.life = this.life - 1 - per evitare che scenda sotto lo 0 (“scoppio” dell’istanza):
- nel metodo display(): aggiungere
- prova temporanea: nel 1° fill() del display():
fill(200, 55, 85, this.life/1000) - separazione visualizzazione (sole istruzioni di disegno) da aggiornamento (sola gestione valori delle proprietà)
- aggiunta metodo update():
- trasferimento codici di aggiornamento delle proprietà da display():
- aggiunta metodo update():
- eliminare istanze “scoppiate”, senza creare confusione con gli indici dell’array
- nel draw(): invertire ordine di lettura:
for (let i=bubbles.length-1; i >= 0; i=i-1) { - display() eseguito solo se istanza non “scoppiata”:
- eliminazione istanza in caso contrario:
- nel draw(): invertire ordine di lettura:
- far apparire le nuove istanze sopra le altre
- nel mousePressed(): sostituire
bubbles.push(b)conbubbles.unshift(b)
- nel mousePressed(): sostituire
Modifiche complessive
Codice finale
Link utili
Esempio di partenza: How to Program Interactive Art With p5.js.
Introduzione ai concetti base di p5.js: Introduzione a p5.js
Guida di riferimento alle variabili e alle istruzioni di p5.js: P5.js Reference