Titolo piuttosto criptico oggi, ma di cosa stiamo parlando? Delle texture atlas (aka sprite sheets), probabilmente il più importante strumento per migliorare le performance dei nostri videogiochi. Ma prima di addentrarci e scoprire di cosa si tratta esattamente facciamo una piccola premessa, che ci aiuterà a capire quale problema andiamo a risolvere con questo strumento.
Ricordate la precedente lezione? Nell’esercizio avevamo aggiunto una sola sprite e le prestazioni non ne avevano minimamente risentito, ma cosa accadrebbe se provassimo a caricare un discreto numero di sprite? Ve lo dico io: il gioco diventerebbe ingiocabile!
A scopo dimostrativo ho modificato il codice scritto nella lezione 3 creando non una, ma 50 sprite posizionate in maniera random in una zona dello schermo.
Come potete notare dall’immagine qui sotto le prestazioni sono notevolmente calate, soprattutto considerando che quelle sprite sono fisse e non vengono animate!
Un’aspetto che non si riesce ad “apprezzare” da questa immagine è il notevole aumento del tempo di caricamento del gioco: in fase di avvio, per diversi secondi, il framerate è stato di 5/7 fps… e tutto questo sul simulatore!
Pensate a cosa accadrebbe su un dispositivo magari vecchiotto come un iPhone 3.
Ma perché questo degrado? Per capirlo a fondo dovremmo conoscere cosa succede al livello di OpenGL ES, ma visto che stiamo usando Cocos2d proprio per evitare di addentrarci in questa tecnologia, ci basterà sapere che la creazione di molte sprite, ciascuna con la sua immagine, introduce un notevole overhead dovuto al caricamento del file immagine dal disco in memoria. Sarebbe comodo poter usare un unico file così da minimizzare questo overhead, ed è infatti l’idea che sta alla base delle texture atlas (vengono chiamate anche sprite sheet).
Ma cos’è una texture atlas?
Una texture atlas è un’immagine dove sono state inserite, una di fianco all’altra, tutte le immagini di un personaggio o di una scena, come potete vedere in questa figura:
Anche in questo caso sta al programmatore decidere quali immagini inserire all’interno di una texture, ovviamente cercando di raggruppare immagini da utilizzare nello stesso contesto.
Le dimensioni contano
Le dimensioni contanto! Chi dice il contrario… non ha mai avuto a che fare con lo sviluppo di videogiochi! Se non fosse chiaro sto parlando della dimensione delle sprite, che ha un impatto notevole sul consumo di memoria dei nostri device.
Come se la memoria non fosse già preziosissima, sui “vecchi” device (parliamo di iPhone 3) è presente una limitazione che impone il caricamento in memoria solo immagini la cui dimensione sia una potenza di due. Se ad esempio la vostra sprite misura 129×129 pixel in memorià sarà rappresentata da una immagine 256×256.
Cocos2d include delle funzionalità per gestire correttamente anche le sprite con dimensione non potenza di due (NPOT) ma questa opzione deve essere abilitata specificatamente.
Nel file ccConfig.h sono presenti alcune direttive al compilatore, quella che ci interessa è:
#ifndef CC_TEXTURE_NPOT_SUPPORT
#define CC_TEXTURE_NPOT_SUPPORT 1
#endif
Nel vostro caso dovrebbe essere 0, portatela quindi ad 1 e leggete con attenzione il commento, scoprirete che questa opzione verrà abilitata di default sulla prossima release di cocos2d, ottima notizia!.
Come creare una texture atlas (o sprite sheets)
Ma come si può generare una texture atlas come quella che abbiamo appena visto? Esistono decine di programmi per farlo e volendo lo si potrebbe fare anche “a mano” perché quello che serve è mettere le immagini affiacate in un’unica immagine ed annotare per ciascuna immagine l’origine (in termini di pixel).. un lavoraccio!
Utilizziamo quindi un programma che si chiama Zwoptex (http://zwopple.com/zwoptex/). Questo programma non è gratuito ma il costo è veramente basso e anche nella sua versione non-registrata permette di rispondere alle esigenze più comuni.
Scarichiamolo quindi dal sito e avviamolo, si aprirà quindi una finestra in cui dovremo cliccare su “Create a new document”:
L’interfaccia del programma non è complessa, ma a prima vista potrebbe disorientare.
Iniziamo con l’importare delle immagini che abbiamo precedentemente realizzato cliccando sul pulsante “import”. Se volete potete scaricare le immagini da utilizzare da QUESTO indirizzo (io ho le ho recuperate da questo sito: http://www.retrogamezone.co.uk/doremifantasy.htm) e sono state rippate da un videogioco che si chiama DoReMi Fantasy.
Come potete notare le immagini appena importate sono visibili nell’elenco sulla destra, mentre nell’immagine al centro appaiono tutte sovrapposte. Assicuriamoci quindi che la dimensione del documento sia adeguata a contenere tutte le nostre sprite (nell’esempio ho selezionato 128×128) e clicchiamo sul pulsante “layout”. Il risultato dovrebbe essere quello visibile in figura:
Tra le varie opzioni di questo programma forse la più importante è accessibile dalla checkbox “trimmed”, che permette di eliminare (se presente) l’area trasparente intorno alle nostre sprite così da diminuire lo spazio occupato e permettere l’overlapp di più sprite. Questa opzione però non cambierà le dimensioni a runtime della nostra sprite perché Zwoptex memorizza la quantità di pixel che ha eliminato e la reinserisce a runtime così che possiamo gestire il tutto come se niente fosse accaduto.
Abilitiamo quindi l’opzione e vedremo che ora il programma riesce a far stare 5 immagini da 32×32 pixel in un’unica riga da 64 pixel!
Eliminando anche “borderpadding” e “sprite spacing” arrivo a contenere il tutto in un’unica texture atlas da 64×32 pixel, non male!
A questo punto possiamo esportare il frutto del nostro lavoro, che consisterà in un’immagine png ed un file *.plist contenente tutte le informazioni per recuperare la singola sprite.
Clicchiamo su “Publish Settings” e configuriamo tutto come visibile in questa immagine:
Clicchiamo su “Done” e infine su “Publish” per esportare il nostro lavoro.
Il risultato è composto da questi due file:
Come si può ben vedere il file plist contiene le informazioni necessarie per recuperare e ricostruire le singole sprite.
Animiamo la nostra sprite
Per imparare ad usare le texture atlas creeremo un nuovo progetto cocos2d in cui animeremo la nostra piccola DoReMi posizionandola al centro dello schermo.
Procediamo quindi (come abbiamo già fatto altre volte) con la creazione di un nuovo progetto cocos2s, che io ho chiamato “LearnAtlas”.
Copiamo all’interno del progetto i due files prodotti da Zwoptex trascinandoli sul Navigator di XCode (l’elenco delle risorse a sinistra).
Esaminiamo il metodo init della classe HelloWorldLayer ed eliminiamo tutto il codice riguardante la creazione della label, al suo posto visualizzeremo la nostra animazione.
Vediamo come di consueto il codice nella sua interezza e a seguire la spiegazione:
-(id) init
{
if( (self=[super init])) {
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"run_default.plist"]; //1
NSMutableArray *runningFrame = [NSMutableArray array];
for(int i = 0; i < 4; ++i) {
[runningFrame addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:@"run_000%d.png", i]]];
} //2
CCAnimation *runningAnimation = [CCAnimation
animationWithFrames:runningFrame delay:0.15f]; //3
CCSprite *doremiSprite = [CCSprite spriteWithSpriteFrameName:@"stay.png"];
CGSize s = [[CCDirector sharedDirector] winSize];
[doremiSprite setPosition:CGPointMake(s.width / 2, s.height / 2)]; //4
CCAction *walkAction = [CCRepeatForever actionWithAction: [CCAnimate actionWithAnimation:runningAnimation restoreOriginalFrame:NO]]; //5
[doremiSprite runAction:walkAction]; //6
[self addChild:doremiSprite]; //7
}
return self;
}
1. Aggiungiamo al singleton CCSpriteFrameCache il file plist generato da Zwoptex
2. Creiamo un array contenente 4 sprite, ciascuna sprite è recuperata proprio dal singleton CCSpriteFrameCache attraverso il metodo spriteFrameByName: al quale bisogna passare il nome dell'immagine originale che abbiamo inserito dentro la texture atlas. In questo caso le immagini si chiamano run_0000.png, run_0001.png etc.
3. Creiamo un'animazione utilizzando i frame inseriti nell'array e inserendo un delay di 0.15 secondi tra un frame ed il successivo
4. Creiamo la sprite della piccola DoReMi utilizzando l'imagine stay.png che la mostra frontalmente. Questa immagine è recuperata come le altre dalla texture atlas.
5. Creiamo l'azione che ripeterà indefinitivamente l'animazione definita al passo 3
6. Assegniamo l'azione alla nostra sprite
7. Aggiungiamo la sprite alla nostra scena.
Il risultato sarà questa sprite che sgambetta felice al centro del nostro schermo:
Nella prossima lezione approfondiremo il comportamento delle sprite imparando ad eseguire le azioni sulle sprite stesse. Per qualsiasi dubbio o chiarimento vi invito a postare sul nostro forum nell'apposita sezione dedicata al corso di cocos2d.
Alla prossima









15 Responses to “04. Sprite e texture atlas (sprite sheets): animiamo in nostri personaggi”
23 Luglio 2012
04. Sprite e Texture atlas: animare un personaggio | Corso gratuito di programmazione videogame per iPhone e iPad | Vivi Capena[…] Inizieremo dunque da una panoramica dei problemi tipici che salterebbero fuori se iniziassimo ad importare sprite a raffica nel nostro progetto, scopriremo cosa sono le texture atlas, vedremo come si creano (tranquilli, non faremo nulla a mano, useremo un utile programmino) e passeremo nel vivo dell’azione dando vita al nostro primo personaggio che si muoverà felice all’interno del nostro schermo accompagnandoci fino alla prossima lezione in cui impareremo ad eseguire delle azioni sulle sprite stesse. Tutti pronti quindi? Allora non vi resta che addentrarvi nella nuova lezione seguendo il seguente indirizzo. […]
23 Luglio 2012
04. Sprite e Texture atlas: animare un personaggio | Corso gratuito di programmazione videogame per iPhone e iPad - iPhone Italia Blog[…] Inizieremo dunque da una panoramica dei problemi tipici che salterebbero fuori se iniziassimo ad importare sprite a raffica nel nostro progetto, scopriremo cosa sono le texture atlas, vedremo come si creano (tranquilli, non faremo nulla a mano, useremo un utile programmino) e passeremo nel vivo dell’azione dando vita al nostro primo personaggio che si muoverà felice all’interno del nostro schermo accompagnandoci fino alla prossima lezione in cui impareremo ad eseguire delle azioni sulle sprite stesse. Tutti pronti quindi? Allora non vi resta che addentrarvi nella nuova lezione seguendo il seguente indirizzo. […]
26 Luglio 2012
KlaroOttima serie di tutorial, sono ansioso di vedere le prossime lezioni!
28 Luglio 2012
klaus91Ciao! Io ho un problema: quando con Zwoptex, dopo aver creato l’immagine, faccio “publish” mi da sempre questo errore: http://imageshack.us/photo/my-images/84/schermata072456137alle2.png/
Ho provato più volte in tutti i modi ma dice sempre così.. Mi sai dire cosa potrei aver sbagliato??
Grazie e complimenti per i tuoi corsi che seguo sempre!!
2 Agosto 2012
MarcelloScusatemi, ma nelle immagini le sprite sono inserite singolarmente, mentre nel link fornito l’immagine è unica. Come procedere?
2 Agosto 2012
MarcelloE in ogni caso anche io ho il publish error di cui sopra.
2 Agosto 2012
MarcelloSono riuscito a risolvere il tutto e ho fatto un video in cui spiego come risolvere i problemi che ho incontrato tra cui quello della pubblicazione con Zwoptex, spero di esservi stato di aiuto:
http://www.youtube.com/watch?v=Cbp2cUWMxaY
2 Agosto 2012
ignaziocsto guardando il video, innanzitutto infinite grazie! ho visto che diversi utenti hanno avuto difficoltà ma in ufficio in questo periodo pre-ferie mi stanno facendo impazzire quindi non ho avuto neanceh un minuto libero!
2 Agosto 2012
ignaziocringrazio nuovamente Marcello per il video che ha realizzato. L’errore con il quale vi siete imbattuti credo che sia molto semplice. In pratica Zwoptex do default usa quelle variabili per la pubblicazione dei file che dipendono da dove avete salvato il progetto stesso di Zwoptex….in pratica se create un file nuovo e provate direttametne a pubblicare, prima ancora si salvarlo lui non sa dove pubblicare i file e quindi vi da errore. Per risolverlo o seguite il consiglio di Marcello, specificando quindi manualmente dove salvare i file oppure salvate prima il progetto di Zwoptex in una cartella.
2 Agosto 2012
MarcelloGrazie a te attendo con ansia nuovi tutorial, per adesso mi cimento nel numero 5 che devo ancora fare 🙂
28 Agosto 2012
SalvatoreBuongiorno a tutti!
Cercavo un aiutino,dopo aver eseguito tutto la procedura non mi avvia l’applicazione,restituendomi questo tipo di problema:
‘animationWithFrames:delay:’ is deprecated
e
‘animationWithFrames:delay:’ is deprecated
Qualcuno gentilmente mi sa dire dove sbaglio,
ho anche compilato come il codice ma nulla,l’unica cosa anomala che ho notato e che quando creo il nuovo progetto a differenza del video a me manca la cartella
GameConfig.h..
Ringrazio in anticipo
1 Settembre 2012
matteosalve a tutti io ho un problema…..quando faccio run il gioco non parte! c’è solo l’immagine di cocos2d….help vi prego
23 Settembre 2012
m3rLin0Prova a salvare il file del progetto prima!
23 Settembre 2012
Ignaziocsalva il file. ne abbiamo già parlato
5 Novembre 2012
EmanuelDXA me non funziona…sarà che ho usato iOS 6.0?
Non capisco che ha…ho seguito tutti i passi…più e più volte e il programma dopo l immagine di caricamento di cocos mi ritorna ad xcode! Grazie in anticipo per l aiuto