Vai al contenuto

ūüď£ sulla piattaforma e-learning di Codice Inutile sono disponibili i miei corsi: Introduzione alla programmazione e ūüÜē Introduzione all'Arte Generativa

Esercizio: Bouncing Ball, parte 1

ūüď¨ Per rimanere aggiornato sui prossimi articoli e su altri contenuti di creative coding, puoi iscriverti a questa newsletter. Per farlo √® sufficiente inserire il tuo indirizzo e-mail nel campo qui sotto.

Puoi leggere l'archivio qui. Powered by TinyLetter

Con il post di oggi, cominciamo a lavorare a un classico problema di programmazione che raccoglie¬†gran parte delle nozioni viste finora. L’evoluzione di questo esercizio comprender√†, ovviamente, l’utilizzo di funzioni personalizzate e ci servir√† per¬†cominciare a parlare di¬†programmazione orientata agli oggetti.

Punto di partenza

Il nostro obiettivo √® scrivere un programma in cui faremo muovere un¬†cerchio¬†all’interno della finestra. Una volta raggiunto¬†un bordo, il nostro cerchio non dovr√† fermarsi o “sparire” uscendo dallo spazio a nostra disposizione ma dovr√†¬†invertire la direzione del suo movimento.

Per comodit√†¬†e per seguire un modello di sviluppo coerente, suddivider√≤ il nostro obiettivo in problemi pi√Ļ semplici che affronter√≤ uno alla volta facendo riferimento ai post in cui abbiamo gi√† trattato problemi simili.

Disegniamo il cerchio e facciamolo muovere in una direzione

Questa √® la parte pi√Ļ semplice: ricordate il post¬†Variabili in Processing: operazioni matematiche?

A differenza dell’esempio sopra citato, creiamo uno sketch con due variabili: ellipseX e ellipseY¬†che utilizzeremo per determinare la posizione del cerchio nella finestra.

int ellipseX;
int ellipseY;

void setup() {
  size(700, 500);
  ellipseX = 0;
  ellipseY = height/2;
}

void draw() {
  background(0);
  ellipse(ellipseX, ellipseY, 50, 50);
  ellipseX++;
}

Il programma funziona correttamente: il cerchio si muove da sinistra verso destra. L’unico problema √® che una volta raggiunto il bordo destro, la variabile ellipseX continua ad aumentare il suo valore di 1 fino a far scomparire il cerchio. Attenzione: il nostro cerchio √® sparito dalla finestra ma, anche se noi non lo vediamo, sta proseguendo il suo movimento verso destra.

Abbiamo raggiunto il bordo?

int ellipseX;
int ellipseY;

void setup() {
  size(700, 500);
  ellipseX = 0;
  ellipseY = height/2;
}

void draw() {
  background(0);
  ellipse(ellipseX, ellipseY, 50, 50);
  if(ellipseX < width) {
    ellipseX++;
  }
}

Inseriamo un semplice controllo condizionale: se ellipseX è minore della larghezza della finestra aumentiamo la variabile. Quando ellipseX sarà uguale a 700, in questo caso specifico, il cerchio si fermerà.

Invertiamo la direzione del movimento

A questo punto dobbiamo invertire la direzione del movimento. Normalmente si è portati a pensare a una cosa del genere:

int ellipseX;
int ellipseY;

void setup() {
  size(700, 500);
  ellipseX = 0;
  ellipseY = height/2;
}

void draw() {
  background(0);
  ellipse(ellipseX, ellipseY, 50, 50);
  if(ellipseX < width) {
    ellipseX++;
  } else {
    ellipseX--;
  }
}

Se avviate questo sketch vi accorgerete, però, che il cerchio non torna indietro. Com'è possibile? Analizziamo i valori che assume la variabile ellipseX: ricordatevi che è sempre possibile inserire println(); per fare il debugging.

Cliccando su Run, il valore di ellipseX è uguale a 0. A ogni ciclo draw() ellipseX viene aumentato di 1 quindi la variabile assumerà i valori, 1, 2, 3 ecc... fino ad arrivare a 700. Chiaramente a ogni ciclo viene effettuato il controllo if: se ellipseX è minore della variabile width (che ha valore 700) allora verrà aggiunto 1.

Quando ellipseX assume il valore 700, la condizione if(ellipseX < width) sarà false e scatterà il blocco di codice presente nell'else e quindi a ellipseX verrà assegnato un valore di 699. Al ciclo successivo il controllo if(ellipseX < width) sarà di nuovo true e quindi alla variabile verrà sommato 1 e tornerà a un valore di 700.

Questo si ripeterà all'infinito e la variabile assumerà solo valori pari a 699 o 700 bloccando, di fatto, il movimento del cerchio.

Per invertire la direzione del movimento dobbiamo fare qualcosa in pi√Ļ:¬†aggiungere una variabile per controllare la direzione dello spostamento a cui invertiremo il segno (da positivo a negativo) per far si che il cerchio torni effettivamente indietro.

Per cambiare il segno di un numero da positivo a negativo sappiamo che è sufficiente moltiplicarlo per -1. Mi rendo conto che, spiegandolo a parole, questo passaggio è un po' complicato; per aiutarvi nella comprensione ho inserito un println() alla fine del codice per mostrare in console i valori di ellipseX e speedX.

Altra puntualizzazione: ho modificato anche il controllo condizionale da if(ellipseX < width) a if(ellipseX > width) per far funzionare il programma correttamente e cambiare il segno solo al raggiungimento del bordo destro.

int ellipseX;
int ellipseY;
int speedX = 1;

void setup() {
  size(700, 500);
  ellipseX = 0;
  ellipseY = height/2;
}

void draw() {
  background(0);
  ellipse(ellipseX, ellipseY, 50, 50);
  if(ellipseX > width) {
    speedX = speedX * -1;
  }
  ellipseX = ellipseX + speedX;
  println("EllipseX: " + ellipseX + " SpeedX: " + speedX);
}

Il nostro cerchio ora torna indietro ma, una volta raggiunto il bordo sinistro, scompare nuovamente dalla finestra.

Ora tocca a voi dimostrare di aver capito come procedere: dovete fare in modo che il cerchio torni indietro una volta raggiunto anche il bordo sinistro e poi, ovviamente, implementare lo stesso procedimento anche sull'asse verticale. La soluzione sarà pubblicata nella seconda parte!

Articolo precedente

Funzioni personalizzate

Articolo successivo

Esercizio: Bouncing Ball, parte 2

Unisciti alla discussione

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.