PROGRAMMARE UN’AUTOMOBILE

In questo tutorial vediamo come programmare in Atomic il movimento di una semplice automobile vista dall’alto.

Concetti che devono già essere assodati per affrontare questo tutorial:

  • Variabili
  • Espressioni
  • Disegnare testo
  • Disegnare immagini
  • Costrutto se
  • Basi della programmazione ad oggetti

Livello d’istruzione minimo consigliato: terza media/prima superiore

EVENTO INIZIA

INSERIRE LA GRAFICA

Iniziamo con il caricare all’interno del progetto l’immagine della nostra auto.

Auto sportiva

foto = ottieni immagine --> (NOME:"internet/images.vectorhq.com/images/previews/be6/green-racing-car-top-view-104981.png") (ORIGINE X: 246.5) (ORIGINE Y: 122.5)

Prima di tutto stabiliamo che la variabile che memorizzerà l’immagine si chiamerà foto.

foto = ottieni immagine --> 

Il disegno si trova a questo indirizzo:
http://images.vectorhq.com/images/previews/be6/green-racing-car-top-view-104981.png

Quindi specifichiamo nell’argomento NOME che l’immagine si trova su internet tramite la parola chiave “internet/“; dopodiché incolliamo l’indirizzo escludendo il protocollo “http://”.

foto = ottieni immagine --> (NOME:"internet/images.vectorhq.com/images/previews/be6/green-racing-car-top-view-104981.png")

L’immagine è larga 493 pixel ed è alta 245 pixel.

Puoi scaricare l’immagine per vedere i dettagli come le dimensioni:
click destro sull’immagine -> salva immagine con nome
click destro sul file dell’immagine scaricata -> proprietà -> dettagli

Quindi per impostare l’origine al centro dobbiamo calcolare 493/2=246.5 e 245/2=122.5

(ORIGINE X: 246.5) (ORIGINE Y: 122.5)

schema origine automobile

Impostare l’origine dell’immagine al centro è molto importante per ottenere uno sterzo realistico: il punto di origine è anche il perno di rotazione. Prova a modificare l’origine per far sterzare l’auto in modo alternativo! (Puoi ottenere effetti come derapate e curve strette/larghe)

Puoi scegliere qualsiasi immagine di un auto vista dall’alto, l’importante è che sia orientata verso destra (destra = 0 gradi).

CREARE L’OGGETTO AUTO

Passiamo quindi alla creazione dell’oggetto vero e proprio tramite la funzione crea un esemplare.

 
crea un esemplare --> (NOME: auto) (IMMAGINE: foto) (SCALA ASSE X: 0.2) (SCALA ASSE Y: 0.2) (benzina: 100) (accelerazione: 0.5) (velocità_massima: 20)

Creiamo un esemplare di NOME auto ed assegniamogli la foto come IMMAGINE che lo rappresenterà sullo schermo.

crea un esemplare --> (NOME: auto) (IMMAGINE: foto)
In questo caso l’esemplare “auto” è un esemplare unico. Si potrebbe definire come l’unico esemplare di un ipotetico oggetto “auto_generica” che comunque non ha senso specificare poiché rappresenterebbe un solo esemplare!

L’immagine è molto grande rispetto alla finestra, quindi la rimpiccioliamo (scaliamo) al 20% (0.2) della dimensione originale tramite gli argomenti SCALA ASSE X e SCALA ASSE Y:

crea un esemplare --> (NOME: auto) (IMMAGINE: foto) (SCALA ASSE X: 0.2) (SCALA ASSE Y: 0.2)

Dichiariamo ora delle variabili locali che ci serviranno più avanti: benzina, accelerazione e velocità_massima.

(benzina: 100) (accelerazione: 0.5) (velocità_massima: 20)
  • benzina indica la quantità di benzina presente nell’auto, quando finisce l’auto si ferma
  • accelerazione indica di quanto aumenta la velocità in pixel*(1/30)secondi
  • velocità_massima indica la velocità massima raggiungibile dall’auto in pixel*(1/30)secondi

CICLO CONTINUO

ACCELLERAZIONE, FRENO e RETROMARCIA

Ora che l’auto è fisicamente presente nell’ambiente è tempo di programmarne il movimento!
Prima di tutto scegliamo con cosa muoverla: in questo tutorial ho usato le frecce della tastiera ma si può utilizzare anche la classica combinazione di tasti WASD.

se tasto freccia su è premuto = vero { ...azione...}   
se tasto freccia giu è premuto = vero { ...azione...}

Iniziamo quindi specificando l’accelerazione tramite la funzione modifica elemento e in particolare l’argomento VELOCITA.

se tasto freccia su è premuto = vero {modifica un elemento --> (NOME: auto)  (VELOCITA: VELOCITA+accelerazione)}
Soffermiamoci sul significato di questo pezzo di codice:

(VELOCITA: VELOCITA+accelerazione)

significa che la VELOCITA è uguale alla VELOCITA (attuale) + l’accelerazione.
Quindi, quando l’auto sarà ferma, il primo istante in cui verrà premuto il tasto il risultato sarà: (0+0.2) che poi diventerà (0.2+0.2) -> (0.4+0.2) -> (0.6+0.2) ecc… In questo modo l’auto aumenta progressivamente la propria velocità.


Scriviamo la stessa cosa anche per la freccia in giù, le uniche due differenze sono:

  • il segno meno al posto del più (velocità negativa = movimento indietro).
  • Moltiplicare l’accelerazione (negativa) per 3 per rendere più reattiva la frenata.
se tasto freccia giu è premuto = vero { modifica un elemento --> (NOME: auto)  (VELOCITA: VELOCITA-accelerazione*3)}

In questo modo lo stesso tasto della retromarcia funge anche da freno quando la velocità è positiva.

GESTIRE LA BENZINA

Per diminuire la benzina presente nell’auto, alle due funzioni modifica elemento scritte sopra basta aggiungere:

(benzina: benzina-0.1)

In questo modo la benzina diminuisce ogni volta che premiamo l’acceleratore. Il meccanismo è lo stesso visto sopra per la velocità/accelerazione.

se tasto freccia su è premuto = vero { modifica un elemento --> (NOME: auto)  (VELOCITA: VELOCITA+accelerazione) (benzina: benzina-0.1)}                                             
se tasto freccia giu è premuto = vero { modifica un elemento --> (NOME: auto)  (VELOCITA: VELOCITA-accelerazione*3) (benzina: benzina-0.1)} 

Ora bisogna controllare se c’è abbastanza benzina nell’auto per farla muovere, aggiungiamo questa condizione prima del blocco che abbiamo appena scritto:

se benzina del auto è maggiore di 0 

Il risultato finale del blocco che gestisce velocità, freno, retromarcia e benzina è il seguente:

//Accellerazione, freno e retromarcia
se benzina del auto è maggiore di 0 
{ 
se tasto freccia su è premuto = vero { modifica un elemento --> (NOME: auto)  (VELOCITA: VELOCITA+accelerazione) (benzina: benzina-0.1)}                                             
se tasto freccia giu è premuto = vero { modifica un elemento --> (NOME: auto)  (VELOCITA: VELOCITA-accelerazione*3) (benzina: benzina-0.1)}   
}

LO STERZO

Vediamo ora il blocco di codice che si occupa dello sterzo dell’auto:

//Sterzo
velocità_assoluta = ottieni il valore assoluto di --> (VALORE: VELOCITA del auto) 
se VELOCITA del auto è diverso da 0 
{
se tasto freccia destra è premuto = vero { modifica un elemento --> (NOME: auto)  (DIREZIONE: DIREZIONE-velocità_assoluta/3)} 
se tasto freccia sinistra è premuto = vero { modifica un elemento --> (NOME: auto)  (DIREZIONE: DIREZIONE+velocità_assoluta/3)}  
modifica un elemento --> (NOME: auto)  (ROTAZIONE: DIREZIONE)      
}

L’unico valore particolare che viene utilizzato in questo blocco è la velocità_assoluta.
Tramite la funzione ottieni il valore assoluto di trasformiamo l’eventuale velocità negativa (retromarcia) in un valore positivo. Questo valore ci servirà nella formula che regola lo sterzo.

velocità_assoluta = ottieni il valore assoluto di --> (VALORE: VELOCITA del auto) 
AD ESEMPIO
Se la VELOCITA è uguale a 5 la velocità_assoluta sarà 5
Se la VELOCITA è uguale a -5 la velocità_assoluta sarà 5

Ora constatiamo una cosa fondamentale: l’auto può sterzare solo quando si muove, ovvero quando la velocità è maggiore di 0 e quando la velocità è minore di 0 (retromarcia). Quindi, detto in modo più sintetico, l’auto può sterzare solo quando la velocità è diversa da 0.

se VELOCITA del auto è diverso da 0 
{

}

Ora modifichiamo la DIREZIONE specificando, in base al tasto premuto, che la direzione è la direzione attuale + (o -) la velocità_assoluta/n, dove n è un valore arbitrario per regolare la reattività dello sterzo (nell’esempio questo valore è 3). Più n è un numero piccolo e più l’auto risulterà maneggevole.

(DIREZIONE: DIREZIONE+velocità_assoluta/3)

se tasto freccia destra è premuto = vero { modifica un elemento --> (NOME: auto)  (DIREZIONE: DIREZIONE-velocità_assoluta/3)} 
se tasto freccia sinistra è premuto = vero { modifica un elemento --> (NOME: auto)  (DIREZIONE: DIREZIONE+velocità_assoluta/3)}

Ora pensiamo alla grafica: la rotazione dell’auto è uguale alla sua direzione.

modifica un elemento --> (NOME: auto)  (ROTAZIONE: DIREZIONE)

Il blocco completo dello sterzo si presenta in questo modo:

//Sterzo
velocità_assoluta = ottieni il valore assoluto di --> (VALORE: VELOCITA del auto) 
se VELOCITA del auto è diverso da 0
{                                             
se tasto freccia destra è premuto = vero { modifica un elemento --> (NOME: auto)  (DIREZIONE: DIREZIONE-velocità_assoluta/3)} 
se tasto freccia sinistra è premuto = vero { modifica un elemento --> (NOME: auto)  (DIREZIONE: DIREZIONE+velocità_assoluta/3)}  
modifica un elemento --> (NOME: auto)  (ROTAZIONE: DIREZIONE)    
}      

L’ATTRITO

Attualmente la nostra auto si ferma solo se premiamo il freno… Ma ovviamente questo comportamento non si verifica nella realtà! Dobbiamo in qualche modo simulare i vari attriti che fanno perdere velocità all’auto (principalmente l’attrito volvente).

//Decelerazione per attrito
se VELOCITA del auto è maggiore di 0 { modifica un elemento --> (NOME: auto)  (VELOCITA: VELOCITA-0.15) }
se VELOCITA del auto è minore di 0 { modifica un elemento --> (NOME: auto)  (VELOCITA: VELOCITA+0.15) } 

Se la velocità è positiva diminuiamola.
Se la velocità è negativa aumentiamola.

LIMITI DI VELOCITA

Purtroppo nella realtà un’auto non può accelerare all’infinito!
Impostiamo quindi dei limiti di velocità:

//Limiti di velocità
se VELOCITA del auto è maggiore di velocità_massima del auto { modifica un elemento --> (NOME: auto) (VELOCITA: velocità_massima)}
se VELOCITA del auto è minore di -6 { modifica un elemento --> (NOME: auto) (VELOCITA: -6)}

Utilizziamo la variabile locale velocità_massima per la massima velocità positiva e un valore negativo più basso (-6) per la velocità negativa massima della retromarcia.

ULTIMI DETTAGLI

Per completare il progetto rendiamo infinita l’area di gioco utilizzando la funzione trasporta elemento al lato opposto quando esce dalla finestra e scriviamo il valore attuale della benzina nella forma “Benzina: xxx” tramite la funzione ottieni testo combinato.

//Teletrasporto
trasporta elemento al lato opposto quando esce dalla finestra --> (ELEMENTO: auto)

//Disegna la benzina attuale
testo = ottieni testo combinato --> (TESTO 1: "Benzina: ") (TESTO 2: benzina del auto) 
disegna testo --> (TESTO: testo) (X: 20) (Y: 20)

CONCLUSIONI

Questo progetto è molto personalizzabile ed espandibile: può essere la base di un gioco di corse, un gioco di autoscontri oppure l’auto può diventare una navicella spaziale che spara raggi laser… Prova a modificarlo e ad aggiungere elementi per farlo diventare un vero gioco!

Alcuni spunti
Prova a programmare:

  • Taniche di benzina che se prese ripristinano parte del carburante
  • Check point da raggiungere entro lo scadere di un tempo
  • L’auto che spara raggi laser!
  • Marce con cambio automatico
  • Marce con cambio manuale
  • Ostacoli da evitare