Anna De Luca – Generative Landscape

L’esercitazione assegnata prevedeva la progettazione di un paesaggio immaginario in costante trasformazione, a tema libero. Ho scelto di sviluppare una scena marina dominata da un faro immerso tra le onde del mare. Attraverso la transizione fluida tra tre fasi temporali (giorno, tramonto e notte) e l’integrazione di movimenti organici, come il moto ondoso stratificato e il volo degli uccelli, ho cercato di creare un’esperienza estetica rilassante, evocativa e in continua evoluzione.

    • Tempo: contatore che cresce ogni frame, alimenta il ciclo giorno/notte;
    • OffsetOnde: contatore che cresce ogni frame, anima lo scorrimento delle onde;
    • Uccelli: array che contiene i 5 oggetti “uccello”, ognuno con posizione e velocità differenti.
      • Creazione della tela (600×700);
      • Inizializzazione dei 5 uccelli con posizione e velocità casuali.

        a. CICLO GIORNO/NOTTE

        • il tempo cresce ad ogni frame;
        • il cicloGiornoNotte oscilla tra 0 (notte) e 1 (giorno) tramite sin();
        • governa colori e posizioni di tutti gli elementi della scena.

        b. CIELO

        • viene disegnato riga per riga dall’alto verso il basso ed ogni riga interpola tra due colori (c1 in cima, c2 in fondo);
        • entrambi i colori cambiano in base a cicloGiornoNotte;
        • il risultato è un gradiente che evolve nel tempo.

        c. SOLE / LUNA

        • movimento e posizione guidata da cicloGiornoNotte (scende di giorno, sale di notte);
        • il colore cambia in tre fasi: da giallo ad arancione e da arancio e a grigio argentato.

        d. FARO

        • disegnato con coordinate relative tramite translate();
        • isolato dal resto della scena con push() e pop();
        • composto da: corpo, fasce colorate, porta (realizzata con curve di Bezier), finestra, balconata, lanterna, tetto.

        e. ONDE

        • tre strati sovrapposti, ognuno più in basso e più mosso del precedente;
        • forma sinusoidale animata da offsetOnde che scorre ogni frame;
        • il colore di ogni strato cambia tra azzurro chiaro (giorno) e blu scuro (notte).

        f. UCCELLI

        • ogni uccello è disegnato con due semicerchi affiancati (ali));
        • si muovono da sinistra a destra a velocità diversa;
        • quando escono dal bordo destro, riappaiono a sinistra a altezza casuale.

        Mi sono rivolta saltuariamente a Claude, per verificare la correttezza di alcuni passaggi ed ottimizzare la scrittura del codice.

        // Variabili globali

        let tempo = 0;
        let offsetOnde = 0;
        let uccelli = [];

        /* Setup: creazione della tela e di 5 “uccelli” in posizioni casuali, ognuno con una propria velocità (compresa tra 0.2 e 0.4 pixel/frame).
        */

        function setup() {
        createCanvas(600, 700);
        for (let i = 0; i < 5; i++)
        uccelli.push({x: random(width), y: random(80, 250), velocita: random(0.2, 0.4)});
        }

        /* Draw: impostazione della velocità di scorrimento del tempo (tra 0, che corrisponde alla notte, e 1, che corrisponde al giorno).
        */

        function draw() {
        tempo += 0.0008;
        let cicloGiornoNotte = (sin(tempo) + 1) / 2; // imposto un’oscillazione ciclica tra 0 e 1, invece che tra -1 e +1

        /* Creazione del gradiente di colore del cielo. I colori, rappresentati dagli estremi c1 e c2, variano in base alla variabile cicloGiornoNotte.
        */

        for (let y = 0; y < height; y++) {
        let c1 = cicloGiornoNotte < 0.5 ?
        lerpColor(color(80,160,240), color(255,100,50),cicloGiornoNotte2): lerpColor(color(255,100,50), color(10,20,70), (cicloGiornoNotte-0.5)2);
        let c2 = cicloGiornoNotte < 0.5 ?
        lerpColor(color(180,230,255), color(255,180,120), cicloGiornoNotte2) : lerpColor(color(255,180,120), color(30,50,120), (cicloGiornoNotte-0.5)2);
        stroke(lerpColor(c1, c2, y/height)); //impostazione gradiente verticale

        line(0, y, width, y); //disegno di una riga orizzontale larga quanto tutto il canvas che, ripetuta per ogni y, riempie tutto il cielo
        }

        /* Impostazione del Sole, un cerchio che scende e sale nel cielo cambiando colore, guidato interamente da cicloGiornoNotte.
        */

        let soleY = height/2 – 180 + map(cicloGiornoNotte, 0, 1, -60, 120); //il sole scende durante il giorno e sale di notte
        fill(cicloGiornoNotte < 0.5 ? lerpColor(color(255,230,120), color(255,90,50), cicloGiornoNotte2) //cambiamento in 3 fasi : lerpColor(color(255,90,50), color(200,200,220), (cicloGiornoNotte-0.5)2));

        stroke(0);
        ellipse(width/2, soleY, 220);

        /* Costruzione del corpo del faro utilizzando le push () e pop (), le quali rispettivamente salvano lo stato attuale del canvas e lo ripristinano (isolamento delle trasformazioni).
        */

        push();
        translate(width/2, height/2 + 40);
        rectMode(CENTER);
        stroke(0);
        fill(240); rect(0,0,100,260);
        fill(180,40,40); rect(0,-60,100,50); rect(0,40,100,50);
        fill(50); beginShape();
        vertex(-15,120); vertex(-15,100);
        bezierVertex(-15,80,15,80,15,100);
        vertex(15,120); endShape(CLOSE);
        rect(20,-40,15,15,3);
        fill(230); rect(0,-140,120,20);
        fill(200); rect(0,-170,50,40);
        fill(80); rect(0,-200,30,20);
        pop();

        /* Disegno delle onde del mare ed impostazione delle colorazioni in base all’ora del giorno.
        */

        offsetOnde += 0.02;
        let coloriOnde = [
        lerpColor(color(160,200,220), color(40,60,120), cicloGiornoNotte),
        lerpColor(color(140,180,200), color(30,50,100), cicloGiornoNotte),
        lerpColor(color(120,160,180), color(20,40,80), cicloGiornoNotte)
        ]; //in base a cicloGiornoNotte, ogni colore interpola tra una tinta chiara ed una scura

        for (let i = 0; i < 3; i++) { //ciclo esterno
        stroke(0);
        fill(coloriOnde[i]);
        beginShape();
        for (let x = 0; x <= width; x += 10) //ciclo interno
        vertex(x, height-200 + i50 + sin(x0.01 + offsetOnde)(20 + i5)); //determinazione dell’altezza dei picchi (ogni strato è leggermente più mosso del precedente)
        vertex(width, height);
        vertex(0, height);
        endShape(CLOSE);
        }

        /* Disegno degli uccelli ed impostazione del movimento ad altezza casuale e a velocità compresa in un intervallo dato
        */

        noFill();
        stroke(80);
        for (let i=0;i<uccelli.lenght;i++) {
        arc(uccello.x, uccello.y, 20, 10, PI, TWO_PI);
        arc(uccello.x + 15, uccello.y, 20, 10, PI, TWO_PI);

        uccello.x += uccello.velocita; //ad ogni frame, l’uccello si sposta a destra della sua velocità variabile
        if (uccello.x > width + 20) {
        uccello.x = -20;
        uccello.y = random(80, 250);
        }
        }
        }

        Commenti

        Lascia un commento