Bentornati, dopo una piccola pausa estiva, al nostro corso di programmazione videogame per iPhone e iPad con cocos2d. Oggi vedremo un concetto che ci accompagnerà anche nella prossima lezione, parleremo infatti di come aggiungere una illusione di profondità ai nostri videgiochi in 2D.
Se avete giocato almeno ad un platform 2D più recente del primissimo Mario Bros, avrete sicuramente fatto caso che, nonostanze l’assenza di una terza dimensione, i programmatori riescono comunque a fornire un certo effetto di profondità.
Questo effetto viene ottenuto sfruttando un aspetto molto interessante e caratteristico della percezione visiva chiamato “parallasse”.
Wikipedia recita: “La parallasse è il fenomeno per cui un oggetto sembra spostarsi rispetto allo sfondo se si cambia il punto di osservazione.“.
Questo aspetto è quello che permette al cervello di ricostruire le informazioni sulla profondità da un’immagine che altrimenti sarebbe solo 2d. Poiché tra i due occhi c’è una certa distanza è come se cambiasse il “punto di osservazione” quindi nell’immagine recepita dai due occhi gli oggetti “cambiano” leggermente posizione rispetto allo sfondo. Questa differenza viene rapidamente calcolata dal nostro cervello e l’informazione viene utilizzata per ricavare i dati sulla profondità.
Questo fenomeno è chiaramente visibile ad occhio nudo su breve distanza, basta chiudere alternativamente gli occhi e fissare un oggetto vicino, ma è valido anche su scala astronomica, infatti la distanza tra la terra e i pianeti viene stimata effettuando due misurazioni in tempi diversi. Se la terra si trova in posizione diversa l’immagine che si ottiene è diversa e quindi si può calcolare la distanza.
Ok, dopo questa breve incursione del mondo della fisica torniamo al nostro corso per ripondere alla domanda che sicuramente vi starete ponendo: “Ok, bello ma io con cocos che cosa me ne faccio della parallasse?”.
Beh noi sfruttiamo il concetto inverso, se è vero che l’oggetto sembra spostarsi cambiando punto di osservazione, è vero anche il contrario, infatti noi faremo veramente spostare gli oggetti della nostra scena per simulare un cambio di punto d’osservazione. Semplice, no?
Facciamo un esempio più chiaro, immaginate di essere su un treno in corsa e guardare fuori dal finestrino, cosa vedete? Vetrete probabilmente le forme indistinte dei cespugli che scorrono velocissme, mentre sullo sfondo un paesaggio che scorre lento e, ancora più lontano, delle montagne che sembrano immobili. Oggi tenteremo di ricostruire questo effetto con le sprite e le classi cocos2d.
Facciamo i nostri esperimenti con la parallasse creando un nuovo progetto cocos2d, nell’immagine qui in basso potete vedere quello che andremo a realizzare:

Sono evidenti in questa immagine i 4 livelli:
- il primo piano verde scruro
- il secondo piano verde chiaro
- lo sfondo con le montagne innevate
- il cielo con le nuvole
Ci serviranno le immagini, ma prima di darvi il link per il download ragioniamo un attimo e facciamo un paio di conti.
In questo esempio non faremo un vero e proprio scroll continuo, ma simuleremo la profondità muovendo gli oggetti sullo schermo a diversa velocità.
Ci serviranno quindi delle immagini più grandi dello schermo, così da porterle muovere avanti e indietro senza problemi, ma più grandi di quanto? Non è necessario che siano tutte della stessa dimensione!
Partiamo dal livello in primissimo piano, per visualizzare bene l’aminazione ci sposteremo verso destra di 160 punti, quindi ci servirà avere un’immagine lunga 480 + 160 punti = 640 punti. Tradotto in pixel significa 640 pixel per iphone non retina e 1280 per iphone con il retina display.
Ricordo che io utilizzo il simulatore in modalità “non retina” perché altrimenti avrei difficoltà a postare gli screenshot, ma ricordate per i vostri progetti di aggiungere anche le immagini con il suffisso “-hd”.
Per quanto riguarda i livelli successivi bisogna calcolare quanto sarà il loro spostamento quando il primo piano si sposterà di 160punti… la regola è che più il valore tende a zero e più sembrerà lontano e distante.
Facendo alcune prove decidiamo di spostare il livello secondario dell’80% rispetto al primo piano, mentre il livello con le montagne lo spostiamo del 40%, fanno rispettivamente 128 e 64 pixel.
Per il restante livello, quello con le nuvole, potremmo decidere di lasciarlo completamente fermo, ma per ottenere un effetto più carino lo spostiamo di un 10%, ovvero 16 pixel.
In questo modo otteniamo le seguenti misure:
- Primo piano: 640px
- Secondo piano 608px
- Montagne: 544 px
- Cielo: 496px
Trovate le immagini dentro il progetto che potete scaricare seguendo link a fondo lezione.
Quello che faremo sarà quindi incorporare le immagini adatte e poi aggiungere nel nostro progetto di copia un’istanza della classe CCParallaxNode.
Il codice che ci permette di ottenere questo risultato è il seguente:
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {
// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];
CCSprite *lev0 = [CCSprite spriteWithFile:@"liv_0.png"]; //1
CCSprite *lev1 = [CCSprite spriteWithFile:@"liv_1.png"]; //2
CCSprite *lev2 = [CCSprite spriteWithFile:@"liv_2.png"]; //3
CCSprite *lev3 = [CCSprite spriteWithFile:@"liv_3.png"]; //4
lev0.anchorPoint = CGPointMake(0, 0); //5
lev1.anchorPoint = CGPointMake(0, 0); //6
lev2.anchorPoint = CGPointMake(0, 0); //7
lev3.anchorPoint = CGPointMake(0, 0); //8
CCParallaxNode *paraNode = [CCParallaxNode node]; //9
[paraNode addChild:lev0 z:0 parallaxRatio:CGPointMake(0.1f, 0)positionOffset:CGPointMake(0, 0)]; //10
[paraNode addChild:lev1 z:1 parallaxRatio:CGPointMake(0.2f, 0)positionOffset:CGPointMake(0, 60)]; //11
[paraNode addChild:lev2 z:2 parallaxRatio:CGPointMake(0.4f, 0) positionOffset:CGPointMake(0., 45)]; //12
[paraNode addChild:lev3 z:3 parallaxRatio:CGPointMake(1, 0) positionOffset:CGPointMake(0, -20)]; //13
[self addChild:paraNode z:0 tag:0001]; //14
CCMoveBy *move1 = [CCMoveBy actionWithDuration:2 position:CGPointMake(-160, 0)]; //15
CCMoveBy *move2 = [CCMoveBy actionWithDuration:2 position:CGPointMake(160, 0)]; //16
CCSequence *pingpong = [CCSequence actions:move1,move2, nil]; //17
CCRepeatForever *repeatPingpong = [CCRepeatForever actionWithAction:pingpong]; //18
[paraNode runAction:repeatPingpong]; //19
}
return self;
}
Vediamo in dettaglio cosa fa.
#1-4 Creo le 4 sprite utilizzando quattro immagini separate, vale qui lo stesso ragionamento che abbiamo fatto per gli sprite sheet. Il livello 0 è costituito dalle nuvole, il livello 4 dalle montagne in primo piano.
#5-8 Imposto l’anchorPoint della sprite nell’angolo in basso a sinistra. Non è un passo necessario, ma ci semplificherà i calcoli successivi
#9 Alloco un nodo di tipo CCPalarallaxNode, questo speciale oggetto è quello che automaticamente calcolerà lo spostamento delle 4 sprite.
#10-13 Aggiungo al CCPalarallaxNode le sprite che avevo creato, per ciascuna sprite possiamo impostare la sua percentuale di spostamento attraverso la proprietà parallaxRatio.
Ad esempio parallaxRatio:CGPointMake(0.1f, 0) vuol dire che seguirà gli spostamenti lungo l’asse X del 10%, mentre ventuali spostamenti lungo l’asse Y verranno ignorati.
Il secondo parametro positionOffset, specifica invece l’offset da assegnare alle singole sprite, come potete vedere io ho assegnato un offset verticale per far sì che si possano vedere tutte le sprite.
#14 Aggiungo il CCPalarallaxNode alla scena corrente.
#15 – 16 Creo due azioni, per muovere il livello.
#17 Inserisco le due azioni all’interno di una CCSequence
#18 Creo una CCRepeatForver utilizzando la sequenza appena creata
#19 Eseguo l’azione. È importante notare che noi muoviamo l’intero CCPalarallaxNode e lui si occupa di muovere tutte le sprite al suo interno in funzione del parallaxRatio che abbiamo impostato.
In questo modo siamo riusciti ad ottenere con molta semplicità un effetto di simulazione tridimensionale.
Potete scaricare l’intero progetto da qui:
Ed ecco il video in cui potrete vedere il risultato finale:










3 Responses to “6. Come aggiungere profondità ai nostri videgiochi in 2D”
27 Agosto 2012
06. Aggiungere profondità ai videogame | Corso gratuito di programmazione videogame per iPhone e iPad | Vivi Capena[…] Siete pronti dunque per affrontare la nuova lezione? Allora su le maniche e riprendiamo a sperimentare con la sesta lezione che trovate al seguente indirizzo. […]
27 Agosto 2012
06. Aggiungere profondità ai videogame | Corso gratuito di programmazione videogame per iPhone e iPad - iPhone Italia Blog[…] Siete pronti dunque per affrontare la nuova lezione? Allora su le maniche e riprendiamo a sperimentare con la sesta lezione che trovate al seguente indirizzo. […]
27 Agosto 2012
06. Aggiungere profondità ai videogame | Corso gratuito di programmazione videogame per iPhone e iPad | Nextrack[…] Siete pronti dunque per affrontare la nuova lezione? Allora su le maniche e riprendiamo a sperimentare con la sesta lezione che trovate al seguente indirizzo. […]