Vai al contenuto

Modularità delle funzioni

Proseguiamo la nostra esplorazione nel mondo delle funzioni personalizzate e rendiamo lo sketch che abbiamo realizzato con l'esercizio Bouncing Ball (parte 1, parte 2) modulare.

Per diventare dei buoni programmatori è necessario lavorare costantemente alla riscrittura del proprio codice: è un processo continuo di riorganizzazione e ottimizzazione.

Riprendiamo il codice a cui eravamo arrivati con l'ultimo esercizio:

int ellipseX;
int ellipseY;
int speedX = 1;
int speedY = 1;

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

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

Divisione in  moduli

In quanti moduli possiamo suddividere il nostro programma? Rileggiamo il codice e analizziamo ogni porzione di codice:

  • Righe 1 - 4: dichiarazione delle variabili
  • Righe 6- 10: configurazione generale con la funzione setup()
  • Righe 13-14: disegniamo la nostra palla
  • Righe 15-20: controlliamo che la palla non vada oltre i bordi della finestra e, se necessario, invertiamo la direzione del movimento.
  • Righe 21-22: facciamo muovere la nostra palla

Chiaramente i primi due punti non possono essere modificati: le variabili devono funzionare in vari punti del nostro programma quindi sono pubbliche mentre la parte di configurazione è già all'interno della funzione setup().

Gli altri 3 punti, invece, sono tutti all'interno della funzione draw() ma si occupano di tre attività differenti: disegnare, controllare e muovere la palla. Creiamo un modulo per ciascuna di esse.

Ricordo che non dovendo restituire nessun valore, utilizzeremo la parola void e che possiamo nominare ciascuna funzione come preferiamo purché non si utilizzino parole già riservate.

La funzione drawBall() sarà quella dedicata al disegno della palla

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

moveBall() si occuperà del movimento

void moveBall() {
 ellipseX = ellipseX + speedX;
 ellipseY = ellipseY + speedY;
}

E infine checkEdges() verificherà se la palla ha raggiunto un bordo

void checkEdges() {
 if (ellipseX > width || ellipseX < 0) {
 speedX = speedX * -1;
 }
 if (ellipseY > height || ellipseY < 0) {
 speedY = speedY * -1;
 }
}

Bouncing Ball: modulare

Ecco il codice riscritto:

int ellipseX;
int ellipseY;
int speedX = 1;
int speedY = 1;

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

void draw() {
  drawBall();
  checkEdges();
  moveBall();
}

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

void moveBall() {
  ellipseX = ellipseX + speedX;
  ellipseY = ellipseY + speedY;
}

void checkEdges() {
  if (ellipseX > width || ellipseX < 0) {
    speedX = speedX * -1;
  }
  if (ellipseY > height || ellipseY < 0) {
    speedY = speedY * -1;
  }
}

Se clicchiamo su Run non noteremo alcuna differenza di funzionamento tra questo codice e quello incollato a inizio post.

Qualcuno potrebbe giustamente notare che, però, siamo passati da 24 linee di codice a 34: ben 10 righe di codice in più senza aver, di fatto, cambiato nulla nel funzionamento del nostro programma. Di contro, però, il nostro codice è più pulito e leggibile.

Il reale miglioramento si capirà quando, con il prossimo post, cominceremo a parlare di oggetti.