UNIVERSITÀ DEGLI STUDI DI MILANO BICOCCA
FACOLTÀ DI SCIENZE MATEMATICHE FISICHE E NATURALI
Corso di Laurea in Informatica
Analisi, progettazione e sviluppo
di un videogioco tridimensionale
del tipo “Virtual Pet”
per dispositivi di telefonia mobile
SUPERVISORI: - Professor Francesco GARDIN
- Professor Giancarlo MAURI
Relazione della prova finale di:
MAURO GENTILE
Matr. n. 047857
Anno Accademico 2004/2005
Ai miei genitori
e anche un po’ a me stesso,
perché ogni tanto è bello veder realizzati i propri sogni.
Indice
1 Introduzione
pag. 4
1.1
1.2
1.3
1.4
L’industria videoludica ‘mobile’
Tamagotchi
Pokemon Virtual Pet e Tools utilizzati
Risultati dell’analisi
pag. 6
pag. 7
pag. 7
pag. 8
2 L’industria videoludica e il mercato ‘mobile’
pag. 9
2.1
2.2
2.3
2.4
2.5
Storia e stato dell’arte
Le piattaforme esistenti
Analisi comparativa
Il cellulare – telefono e piattaforma ludica
Uno sguardo al futuro
pag.
pag.
pag.
pag.
pag.
9
11
14
19
22
3 Tamagotchi – un caso di studio e un punto di partenza
pag. 24
3.1
3.2
3.3
Storia
Analisi del prodotto
Evoluzione e sviluppi futuri
pag. 24
pag. 26
pag. 27
4 Tools di sviluppo
pag. 30
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
Strumenti grafici e CAD
Linguaggio di programmazione
Editor
Suoni e Audio
Nokia Series60 Software Development Kit
Emulatore
Create_PKG e Create_SIS
OpenGL for Embedded Systems
Cellulari supportati
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
30
32
33
34
35
36
37
37
38
5 Pokemon Virtual Pet
pag. 43
5.1
5.2
5.3
5.4
5.5
Descrizione del gioco
Pokemon Virtual Pet – Fase di sviluppo
5.2.1 I modelli
5.2.2 Primi passi
5.2.3 OpenGL ES
5.2.4 Nokia API
5.2.5 Input e keypad
5.2.6 GUI
5.2.7
Audio
5.2.8
Framework
5.2.9 Pacchetti SIS
Pokemon Virtual Pet – Caratteristiche tecniche
Pokemon Virtual Pet – Il gioco
Pokemon Virtual Pet – L’evoluzione
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
pag.
43
43
44
49
50
53
56
57
58
59
61
61
63
65
6 Conclusione
pag. 67
6.1
6.2
7
Analisi e confronto
Sintesi finale
pag. 67
pag. 69
Appendici
7.1
7.2
7.3
Appendice A - Modelli MilkShape 3D e OpenGL ES
Appendice B - Implementazioni matematiche
Appendice C - Codice Pokémòn Virtual Pet
pag. 72
pag. 94
pag. 103
Bibliografia e Sitografia
pag. 128
Terminologia
pag. 131
Ringraziamenti
pag. 135
1. Introduzione
I dispositivi mobile ( portatili, palmari, cellulari o altro ) nel mondo attuale sono
diventati parte integrante della nostra vita, tanto che sembra improbabile
conoscere qualcuno che ne sia sprovvisto; anche perché oramai su 6 miliardi di
persone, stima della popolazione sul suolo terrestre, più di 2 miliardi di persone
posseggono un telefono cellulare (da Wireless Intelligence, Set 2005). Proprio
per questo tale dispositivo è uno degli obiettivi fondamentali su cui oggi punta
l’industria videoludica.
Scopo di questa tesi è la verifica dell’utilizzabilità degli smarthphone quali
piattaforma evoluta per giochi e applicazioni con grafica tridimensionale,
rispetto a quanto è disponibile nei dispositivi dedicati.
L’incontro tra il settore della telefonia mobile e quello dei videogames è avvenuto
all’incirca una ventina d’anni fa, quando nei primi cellulari distribuiti sul
mercato mondiale appariva, primo tra tutti, l’indimenticabile gioco “Snake”.
Il telefono cellulare da allora ha compiuto molta strada e al giorno d’oggi è
sempre più difficile trovare differenza tra un palmare ed un cellulare, poiché
tante sono le funzionalità e le caratteristiche che hanno in comune.
L’industria dei videogames non ha certamente trascurato il campo mobile, anche
perché è quello che nel 2004 ha fatto registrare un fatturato stimato tra i 175 e i
200 milioni di dollari negli USA, secondo i dati riportati al Global Wireless
Summit tenutosi a Los Angeles nel maggio di quest’anno (da WirelessGaming.it,
Mag 2005). Non è solo l’industria videoludica a puntare su questi dispositivi,
ma anche tutte le varie Aziende di telecomunicazioni (Telecom), che danno
sempre più importanza a servizi con valore aggiunto, quali musica, video,
giochi e suonerie. I cellulari sono quindi costretti ad evolversi velocemente e
cercano sempre di più di somigliare ad altre console portatili.
Il wireless gaming, o mobile gaming, sfrutta inoltre un altro punto di vista
interessante: riesce cioè a sfondare lì dove tutte le altre funzionalità di un
cellulare terminano; grazie alle nuove tecnologie è difatti possibile ragionare in
termini di gioco multiplayer in real-time.
Questo non è però l’ultima trovata tecnologica nel settore mobile: i creatori di
telefoni cellulari e le aziende produttrici di chip e processori, stanno guardando
in direzione della grafica tridimensionale.
Con la tecnologia moderna è possibile creare applicazioni e giochi
tridimensionali: il fine di questa tesi è proprio dimostrare che tutto il lavoro
svolto fino ad oggi rende i dispositivi cellulari, o meglio, gli smartphone, già
capaci di elaborare grafica poligonale e calcoli di geometria computazionale.
All’inizio di quella che è stata definita “era del cellulare”, si rimaneva di stucco
nel constatare che un apparecchio piccolo, quale il telefonino, fosse anch’esso
stato bersaglio dei videogiochi. Con il passare del tempo anche il colore ha fatto
finalmente la comparsa sugli schermi dei nostri cellulari e quindi è nata tutta
quella frontiera, mai esplorata prima, che oggi si identifica con il nome di mobile
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
4
gaming. L’avvento dei cellulari super potenti di ultima generazione permettono
inoltre anche di visualizzare grafica vettoriale e tridimensionale.
Il capostipite di questa nuova generazione di telefoni, denominata poi
smartphone, è stato senza dubbio il Nokia N-Gage, che per la prima volta ha
unito console e cellulare in un unico dispositivo, permettendo l’uso di giochi in
terza dimensione.
Per testare con mano e provare quanto affermato abbiamo creato
un’applicazione apposita che permette di evidenziare la capacità dei telefoni
cellulari nel poter eseguire un gioco, che, pur essendo semplice, sfrutta la
grafica tridimensionale. L’applicazione, oggetto di questa tesi, è una versione
tridimensionale, dedicata ai telefoni cellulari, che trae spunto dal tradizionale
Tamagotchi e ne migliora i punti deboli grazie alla terza dimensione e
all’utilizzo di suoni stereofonici.
Il Tamagotchi è un videogioco, funzionante solamente su dispositivi
appositamente dedicati e consiste nel simulare l’allevamento di un cucciolo
virtuale, un pulcino. Il successo di questo videogame, nonostante la grafica
scarna e i suoni limitati a ‘bip’ hardware, è dovuto essenzialmente alla situazione
di sfida che si crea per il giocatore nel far sopravvivere il cucciolo stesso. Il
gioco infatti consente di nutrire il proprio cucciolo, giocarci insieme, farlo
dormire, lavarlo e controllarne la crescita. La sfida consiste proprio
nell’impossibilità di abbandonare il proprio cucciolo, pena il fatto che se lo si
trascura per molto tempo, questo crescerà deformato o potrà addirittura
perdere la vita.
Il Pokémòn Virtual Pet, il videogioco creato, ed illustrato in queste pagine ha
qualità importanti:
- può essere usato su differenti cellulari,
- può essere interrotto in qualsiasi momento e ripreso successivamente,
come ci si aspetta in una qualsiasi applicazione destinata a telefoni
cellulari,
- sfrutta la grafica tridimensionale, permettendo di avere una visione
completa del cucciolo,
- produce suoni stereofonici, per ottenere maggior realismo.
Il gioco è stato sviluppato per cellulari Nokia, nello specifico, in quanto questa
compagnia finlandese rilascia, a disposizione degli sviluppatori, un Software
Development Kit, una serie di articoli, tutorials e un grande archivio di
documentazione, molto utili per sviluppare applicazioni in linguaggio Java o
C++. Avendo inoltre a disposizione un cellulare della stessa casa si è potuto
verificare e testare immediatamente il comportamento dell’applicazione.
Il linguaggio adoperato è il C++, anche se molti dei giochi fruibili attualmente
sono scritti in Java. Questa scelta dovuta alla mancanza di esperienza nel campo
della programmazione su telefoni cellulari, con esempi e tutorials fruibili
solamente per il C++, ed al fatto che l’implementazione delle API grafiche
tridimensionali utilizzate, le OpenGL for Embedded Systems, risultano funzionanti
solo con questo linguaggio.
Sviluppando l’applicazione per il primo smartphone di casa Nokia, il Nokia
6600, è stato adoperato essenzialmente l’SDK disponibile in combinazione con
la libreria delle OpenGL ES distribuito dalla Hybrid Graphics Ltd. Grazie
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
5
all’utilizzo di queste API grafiche, non ci si è dovuti preoccupare molto delle
dimensioni dello schermo o della velocità di esecuzione, in quanto, sebbene il
telefono adottato per i test risulti essere il meno performante, le dimensioni
dello schermo rimangono costanti in tutti i cellulari della stessa “Series60”, di
cui fa parte il modello Nokia 6600 e la velocità, controllata è stabilita a priori.
Per scrivere, compilare ed effettuare il debugging del codice è stato utilizzato
Microsoft Visual Studio .Net 2003, in modo da poter creare un unico progetto
per poter organizzare meglio i file utilizzati, le librerie adottate ed effettuare
tutte le configurazioni necessarie in modo semplice e veloce, seguendo la
documentazione fornita dalla stessa casa finlandese Nokia.
Per ricreare la grafica tridimensionale si è dovuto ricorrere a librerie esterne
come le OpenGL ES e questo ha reso il lavoro molto più agevole in quanto la
programmazione con queste API è molto diffusa e il materiale disponibile nel
World Wide Web al riguardo è molto ben dettagliato e curato.
Il lavoro svolto ha portato alle seguenti conclusioni.
Il settore della telefonia mobile si sta spingendo sempre più in direzione del
mobile gaming che continua ad essere in forte espansione. I cellulari di ultima
generazione cercano sempre più di diminuire il gap esistente tra un telefono
cellulare e una console portatile: basti pensare che le funzionalità presenti nelle
ultime due console più importanti da poco rilasciate sul mercato mondiale sono
quelle che i produttori di dispositivi cellulari stanno già sponsorizzando per il
loro rilascio, come funzionalità aggiuntive nei telefonini, nel prossimo anno.
Con le capacità attuali gli smartphone possono effettuare rendering di scene
tridimensionali abbastanza complesse e già per il 2006 è stata pensata una
nuova release delle API grafiche adoperate, le OpenGL ES, con importanti
innovazioni e grandi ottimizzazioni. Le applicazioni possibili con la grafica
tridimensionale spaziano oggi in tutti i campi, dalla navigazione satellitare ad
interfacce innovative o ancora ai giochi di ultima generazione. A sfruttare le
nuove tecnologie dedicate a questi sistemi embedded e individuarne le
potenzialità non deve quindi essere soltanto il settore dell’industria dei
videogames.
Grandi passi devono però essere svolti anche dalle case produttrici, come
Nokia, per migliorare i tools presenti negli SDK, primi tra tutti gli emulatori, che
ancora gravano del fatto di non poter essere l’ultimo passaggio di testing della
release finale di un’applicazione.
La tesi si articola seguendo il seguente schema:
1.1 -
L’industria videoludica ‘mobile’
Viene illustrata la tematica del mercato videoludico, la sua storia e la sua
evoluzione. Un riferimento specifico viene fatto all’industria del “mobile
gaming” e, in particolare, a quel settore dedicato alla creazione e allo sviluppo di
videogiochi per console portatili e cellulari.
Successivamente si tratta la storia delle console portatili, le varie evoluzioni, i
miglioramenti e i peggioramenti apportati, gli effetti di questi dispositivi sulla
società e la loro distribuzione nel mondo.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
6
Tra le console presenti sul mercato mondiale attuale, verranno analizzate sia
quelle di grandi case come Nintendo o Sony, sia alcuni dispositivi mobile,
normalmente destinati ad altro uso, come i telefoni cellulari.
Ancora una volta la strada di questa analisi porta ai dispositivi di telefonia
mobile e quindi alle loro modifiche nel corso del tempo e ai prodotti loro
dedicati.
Concentrando così lo studio sui telefoni cellulari e sulle tecnologie offerte nel
suddetto settore, si analizzeranno i vari trend e gli strumenti di sviluppo offerti,
le nuove frontiere dell’industria videoludica in questo campo, facendo poi
particolare riferimento ai cellulari compatibili con le API grafiche adoperate
tridimensionali OpenGL for Embedded Systems.
1.2 -
Tamagotchi
Analizzare il Tamagotchi è stato un passo inevitabile, poichè è impossibile
ricreare qualcosa di innovativo senza una approfondita conoscenza di ciò che lo
ha preceduto. Lo studio è stato effettuato sia utilizzando un dispositivo reale,
un Tamagotchi, sia alcuni emulatori disponibili in rete, sia ricorrendo ad
un’attenta analisi delle informazioni diffuse dalla casa giapponese Bandai, dai
fan e dagli utenti del World Wide Web.
In primo luogo viene proposta la storia di quello che è stato uno tra i prodotti
che più hanno influenzato il mercato mondiale. Il boom ottenuto da questo
dispositivo inizialmente poteva apparire strano e incomprensibile, viste le
qualità grafiche e sonore di questo piccolo videogame. In realtà per carpire i
segreti del suo successo bisognerebbe guardare al di là dell’estetica e
dell’impatto iniziale, concentrandosi sulle emozioni che questo suscita e sulla
sfida di sopravvivenza che permette di intraprendere.
L’analisi del prodotto si sofferma inizialmente su i suoi punti di forza e quelli di
debolezza, e in seguito sulle nuove proposte e i futuri sviluppi. In prima istanza
si è visto come funziona il gioco e quali sono le caratteristiche peculiari
dell’applicazione stessa, successivamente è stato osservato il dispositivo per
apprenderne le fattezze e le caratteristiche tecniche e infine sono state studiate
le varie evoluzioni del gioco e le nuove versioni rilasciate.
1.3 -
Pokemon Virtual Pet e Tools utilizzati
Il gioco è stato completamente ricreato da zero in una versione tridimensionale
dedicata ad alcuni cellulari Series60, scelti innanzitutto per la possibilità di
utilizzare l’implementazione delle OpenGL ES creata dalla Hybrid Graphics
Ltd, in grado di supportare solo alcuni tra i devices della casa finlandese, ed
anche per la possibilità di effettuare direttamente il test dell’applicazione in
prima persona.
Dopo una breve descrizione del gioco, l’analisi del prodotto si concentrerà
dapprima sui tools di sviluppo utilizzati per la creazione dei modelli utilizzati e
del gioco stesso, e quindi andando ad analizzare la modellazione
tridimensionale e il passaggio di texture mapping dei modelli utilizzati.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
7
Successivamente ci si concentrerà su una breve descrizione delle librerie
grafiche tridimensionali, le OpenGL for Embedded Systems, con particolare
riguardo all’implementazione della Hybrid Graphics Ltd utilizzata
nell’applicazione stessa.
Infine si analizzerà concretamente l’applicazione e la sua implementazione, le
caratteristiche tecniche ed una esemplificazione pratica dello svolgimento del
gioco stesso, illustrando sia la modellazione del gioco che una possibile partita
di un utente finale.
Tutti i test sono stati effettuati, in primis, sul primo smartphone di casa Nokia, il
modello Nokia 6600, questo sia per motivi pratici, sia perché, essendo questo il
primo della serie che ha portato innovazione nel campo ‘mobile’ della casa
finlandese, ha delle caratteristiche tecniche di livello abbastanza basso da poter
con certezza affermare che se l’applicazione raggiunge un buon livello di
giocabilità e velocità su questo modello, le stesse qualità saranno di certo
garantite su quelli successivi e quelli futuri, su cui saranno presenti chip
dedicati al calcolo poligonale e all’accelerazione tridimensionale. I test
successivamente effettuati sul modello Nokia 6680, con l’utilizzo di
un’implementazione nativa all’interno del cellulare stesso, hanno confermato le
ipotesi sostenute.
1.4 -
Risultati dell’analisi
L’analisi finale verte nuovamente sul dispositivo utilizzato, il telefono cellulare,
e sull’applicazione creata. Il confronto con la versione originale del gioco del
cucciolo virtuale, il Tamagotchi, risulta poi inevitabile.
Vengono quindi presentate le qualità e le innovazioni apportate con la
creazione di questo videogioco, in seguito vengono analizzati tutti i vantaggi
ottenuti dall’utilizzo di dispositivi cellulari.
In ultima istanza vengono presentati sia i vantaggi ottenuti utilizzando una
grafica tridimensionale, quindi creando dei modelli, le loro animazioni, il gioco
di luci e il texturing, sia quelli ottenuti grazie all’audio stereo, potendo
differenziare i suoni dal classico bip hardware privo spesso di significato e di
alcuno spessore.
Infine si conclude analizzando il futuro vero e proprio del ‘mobile gaming’ e
degli smartphone dedicati all’utilizzo intenso di grafica 3D e audio in dolby
sorround.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
8
2 L’industria videoludica e il mercato ‘mobile’
2.1 - Storia e stato dell’arte
Il mercato mondiale dei videogame varrà 41 miliardi di dollari entro il 2009 (35%
software console, 24% giochi online, 18% hardware console, 9% software portatile,
7% hardware portatile, 7% giochi PC).
Questa è la stima della società di ricerca DFC Intelligence che ha pubblicato,
come ogni anno, il ‘Worldwide Market Forecasts for the Video Game and Interactive
Entertainment Industry’ (Previsioni mondiali per l’industria dei videogiochi e
dell’intrattenimento interattivo). Di questo totale, 31,2 miliardi di dollari (da
23,2 miliardi di dollari nel 2003, +34%) saranno rappresentati dai videogame
(hardware e software) tradizionali, sia portatili che casalinghi (da E-Duesse – Set
2004).
Proprio le piattaforme portatili vivranno la maggiore crescita percentuale, da
3,9 a 11,1 miliardi di dollari (+180%) tra il 2003 e il 2007, favorendo un aumento
della diversificazione dell’offerta e portando a una crescita della spesa media
dei consumatori (dati pervenuti da ‘Game Programming Italia’ – Mag 2005).
Per quanto riguarda invece il mercato del mobile che, secondo quanto afferma la
società di ricerca Frost & Sullivan, si conferma anche a livello mondiale, lo
studio, da essi pubblicato nei giorni scorsi, sottolinea che « L’appeal universale
dei giochi sarà ulteriormente stimolato dalla crescente penetrazione di
dispositivi sempre più sofisticati, portando i profitti del mercato europeo del
mobile gaming da 800,79 milioni di dollari del 2002 a qualcosa come 7 miliardi di
dollari nel 2006 ». Inoltre, la crescente diffusione dei nuovi dispositivi, in grado
di poter usufruire anche dei giochi più recenti e complessi, farà aumentare
conseguentemente l’offerta di contenuti.
« Entro la fine del 2006 » afferma F&S « il mercato del mobile gaming
rappresenterà il 5% del totale dei profitti degli operatori data wireless, ovvero il
30% del mercato globale dei videogame ». Il 2004 è stato in nordamerica un anno
da record per le vendite di software per computer e per console.
Secondo un report stilato da NPD Group e dall’Entertainment Software Association
(ESA, rappresentante dei Publisher), il business globale di videogiochi (escluso
qualsiasi tipo di hardware) ha raggiunto nel 2004 ben 7,3 miliardi di dollari. I
dati riportati mostrano un netto vantaggio dei giochi per console (5,2 miliardi di
dollari, 160,7 milioni di unità), quasi 5 volte superiori a quelli per computer (1,1
miliardi di dollari, 45 milioni di unità) e dispositivi portatili (1 miliardo di
dollari, 42,3 milioni di unità).
Douglas Lowenstein, presidente di ESA, considera tali numeri una prova della
popolarità dei videogiochi fra consumatori di tutte le età e prevede un’ulteriore
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
9
crescita del mercato nei prossimi 5 anni grazie alla nuova generazione di
hardware in arrivo.
Dando un’occhiata al report, si scopre che ben 11 titoli per console hanno
superato il milione di copie, cinquanta hanno varcato la soglia delle 500.000 e
197 hanno raggiunto il traguardo delle 250.000 copie. Fra i titoli per PC, invece, i
numeri sono ben più ristretti, con soli 2 titoli oltre le 500.000 copie e 18 oltre le
250.000. Il quadro tracciato nel report mostra l’affermazione dei titoli d’azione
(30,1%) e di quelli sportivi (17,8%), che da soli occupano quasi la metà
dell’intero mercato. La restante parte si divide equamente fra sparatutto in
prima e terza persona (9,6%), giochi per famiglie o bambini (9,5%), simulatori di
guida (9,4%) e giochi di ruolo (9%). La categoria dei picchiaduro, in costante
calo negli ultimi anni, chiude la classifica con il 5,4% del mercato. Diverse
invece le scelte dei giocatori su PC, che preferiscono i giochi di strategia (26,9%)
e quelli per famiglie (20,3%). Meno omogenea anche la distribuzione degli altri
generi, dove conducono gli sparatutto (16,3%) seguiti dai giochi di ruolo (10%),
avventure (5,9%), sportivi (5,4%) e titoli d’azione (3,9%).
Il mercato oggi sta quindi vivendo una fase di consolidamento a favore delle
grosse realtà. I publisher più grandi tendono ad assorbire le software house più
importanti del mercato, danneggiando i publisher emergenti che possono
contare solo sulla fetta di mercato costituita dai prodotti cosiddetti “low-budget”.
Questo processo spinge le produzioni di videogame verso livelli tecnici altissimi
(impegnando schiere di grafici, ingegneri, programmatori, ecc) e di
conseguenza a costi di produzione difficilmente sostenibili.
Inevitabilmente sono molte le software house che, non adattandosi in tempo alle
nuove regole del mercato, non sono sopravvissute a questo cambiamento
piuttosto radicale. Grosse software house con prodotti eccellenti nei loro
curriculum, forti dei rilevanti introiti iniziali, hanno investito eccessivamente
facendo crescere la loro struttura in maniera sproporzionata rispetto a ciò che i
publisher possono ora offrire ai Third Party Developer.
Da questo scaturisce quindi la necessità per i Game Developers di avere alle
spalle un publisher forte, con una buona licenza da sfruttare per garantirsi un
rientro tale da coprire le spese sostenute per lo sviluppo e per il marketing
nonché ricavare degli utili sulla vendita del prodotto: senza una licenza forte,
una grande tecnologia o concept vincente il publisher non investe.
Il mercato videoludico rappresenta comunque un vasto e ancora immaturo
campo di battaglia, dove le offerte, le tecnologie e le innovazioni sono pronte a
gettarsi nella mischia. Nel prossimo futuro, grazie al crescendo di collegamenti
alla rete globale di internet e alla sua maggiore diffusione nel mondo, la
domanda si orienterà sempre più verso i cosiddetti online game, dove gli utenti
possono confrontarsi con persone sparse nel mondo, popolare luoghi virtuali e
aprire nuove frontiere al divertimento elettronico sino ad ora poco solcate. Le
tariffe di connessione sempre più accessibili, i cellulari di nuova generazione e
le moderne tecnologie di comunicazione fanno sì che realizzare applicazioni
ludiche per queste nuove “piattaforme” sia un must nel prossimo futuro.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
10
2.2 - Le piattaforme esistenti
Una console portatile è uno strumento elettronico leggero e compatto, utilizzato
principalmente per l’esecuzione di videogiochi. A differenza delle rimanenti
console, diciamo fisse, il controller, lo schermo e le casse per l’audio sono parte
integrante dell’unità stessa. Sin dal 1970 diverse compagnie, come la Coleco,
Milton-Bradley o la stessa Nintendo, hanno prodotto alcune console portatili,
oltre a quelle da tavolo. Caratteristica di questi tipi di strumenti era quella di
poter utilizzare un unico gioco e quindi oggi non vengono più considerate vere
e proprie console in quanto ci si riferisce ad esse come ad uno strumento
portatile con cui poter fruire differenti videogames.
Pioniere di questo genere fu Smith Engineering, creatore della prima vera
console portatile a cartucce intercambiabili: il Microvision. Messo sul mercato
nel non tanto lontano 1979 dalla Milton-Bradley (la famosa MB, casa produttrice
di giocattoli come Twister, Indovina Chi? o Forza4), il Microvision poteva
contare su uno schermo LCD di 16x16 e un controller chip intercambiabile per gli
undici diversi titoli esistenti sul mercato, permettendo così di avere un pad
diverso per ognuno di essi (dati: SpazioGames.it).
Solo un anno dopo, nel 1980, fecero il loro ingresso
sul mercato i famosi Game & Watch di Nintendo:
piccole e sottili console monotematiche con schermo
a cristalli liquidi e un orologio integrato. È
interessante notare che è con questo prodotto che la
Nintendo introdusse un elemento che avrebbe
cambiato la storia e il design di tutte le sue console:
la croce direzionale, invenzione del famoso Gunpei
Yokoi, lo stesso che diede poi origine alla console più
venduta della storia: il GameBoy.
Sempre nei primi anni ’80, Atari, leader del primo
mercato di console casalinghe, decise di buttarsi
nell’allora incerto e quasi inesplorato mercato di
quelle portatili. Allan Alcorn, Harry Jenkins e Roger
Hector, ingegneri di Atari, si misero al lavoro e nel
1981 fecero esordire a New York l’Atari Cosmos. In
questa console si poteva osservare il primo tentativo
di introdurre la terza dimensione, che non si deve
Figura 1 - Game & Watch
intendere come impiego dei poligoni, effettivamente
un po’ improbabile nel 1981, ma un effetto ottenuto attraverso l’utilizzo di
immagini olografiche, atte a dare la sensazione di profondità. Anche questa
console portatile aveva a disposizione diversi giochi, otto per la precisione, il
cui utilizzo era reso possibile grazie all’intercambiabilità delle cartucce. Questa
console non ebbe forse il successo sperato, ma sicuramente è apprezzabile il
tentativo di innovazione per il settore.
Dopo l’esperienza dei Game & Watch, Gumpei Yokoi creò, quindi, a capo di un
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
11
team design di nome R&D1, il primo Game Boy, la più famosa console al
mondo. La casa Nintendo era intenzionata a creare il primo sistema di
intrattenimento videoludico extra familiare, mentre era ancora alle prese con il
NES portatile, che poi non venne più ultimato. La console fu inizialmente
contestata per le sue dimensioni ridotte, ma questo non impedì comunque il
successo ricevuto sin nei suoi primi tre anni di vita. Questo strumento portatile
si presentava inizialmente di colore biancastro, con due pulsanti rossi e la
famosa croce direzionale e con la possibilità di poter utilizzare cartucce
interscambiabili.
Nel 1989 la Atari cercò di controbattere alla
supremazia di Nintendo producendo ‘Lynx’, in
realtà creata nel 1987 da Epyx ed acquistata e
modificata da Atari. Questa console oltre che per
le evidenti dimensioni e l’andamento orizzontale
dell’impugnatura, prevedeva, per la prima volta
nel corso della storia, lo schermo retro illuminato
e un impiego totale dei colori nei giochi. Queste
caratteristiche minavano però la durata delle
Figura 2 – Atari Lynx
batterie, che era all’incirca di un’ora. Un’altra
caratteristica saliente del Lynx era che fu la prima console ad impiegare il gioco
in rete.
Sempre in risposta al predominio che in quegli anni andava man mano
acquisendo Nintendo, nacquero molte altre console portatili, che non
raggiunserò però lo stesso successo, sia perché molte erano ancora
monotematiche, sia perché non si riusciva comunque a raggiungere un livello di
grafica migliore di quello del GameBoy, che nel futuro sarà poi il suo grande
punto debole.
Qualche anno più tardi, nel 1990, nacque, proprio con l’intento di minare a
questo difetto della console di casa Nintendo, il Game Gear, di Sega, che pur
avendo una vasta gamma di giochi a disposizione, lo schermo a colori e la
possibilità di essere addirittura convertito in televisione, non ebbe comunque lo
stesso successo, forse anche per il costo poco più elevato.
Il GameBoy subì poi alcune variazioni,
raggiungendo quindi la soluzione al suo problema,
con lo schermo a colori del GameBoy Color, di
dimensioni maggiori. Una caratteristica che ne ha
permesso comunque il successo ed è stato il suo
punto di forza è stata la sua
retrocompatibilità con la
console monocromatica.
Figura 4 - Game Boy
Micro
Nel 2001 Nintendo ha
rilasciato sul mercato una Figura 3 – Game Boy Advance SP
versione con pulsanti extra,
schermo più largo e una potenza di calcolo maggiore
rispetto al suo predecessore, il GameBoy Advance e
successivamente con un design più innovativo il Game
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
12
Boy Advance SP.
Bisogna aspettare il 2004 per vedere il vero e proprio successore del GameBoy,
sempre prodotto da Nintendo: il Nintendo DS. Questa console è caratterizzata
da due schermi LCD, di cui uno dei due sensibile al tatto, e da una potenza di
calcolo nettamente superiore. Chiaramente un suo punto di forza è ancora la
compatibilità con i giochi del Game Boy Advance. La capacità di collegarsi
senza fili per effettuare della partite multigiocatore ne fanno inoltre una tra le
console più innovative del momento.
Nell’autunno del 2005 è invece uscita, in Italia, la PlayStation Portable o PSP, di
casa Sony, già leader delle console da tavolo, che è considerata la maggior
sfidante della nuova console di Nintendo. Il suo costo è un po’ più elevato, ma
ha sicuramente dei vantaggi non indifferenti, tra
cui un’incredibile potenza di calcolo, mantiene la
possibilità di partite multigiocatore, senza
necessità di cavi, e ha sostituito le ormai obsolete
cartucce con una nuova tecnologia, chiamata
UMD, acronimo di Universal Media Disk, che è un
supporto ottico di 1,8 GB, utilizzato sia per i
videogiochi, sia per la musica che per i film.
A tutte queste console va chiaramente aggiunto un
dispositivo
che ha spopolato in tutto il mondo e
Figura 5 – Universal Media Disk
che ha messo in crisi molte delle società sopra
citate per cercare di riconquistare il predominio: il Tamagotchi. Questo
dispositivo, pur essendo una console monotematica e senza l’ausilio di colori o
suoni differenti da semplici bit hardware, ha ottenuto un (forse) insperato
successo in tutto il mondo. Il segreto di tanta popolarità non è però da cercare
nella console dedicata, ma nel gioco stesso, che è riuscito in poco tempo ad
attirare l’attenzione di grandi e piccini, sia favorevoli che contrari.
Questo dispositivo, poi evolutosi in differenti versioni, tra cui l’ultima, il
Tamagotchi Connexion, non è però destinato ad ottenere un successo (quasi)
permanente, nonostante il suo basso costo e le piccole dimensioni, a causa della
sue monotematicità, della grafica e dei suoni, sue grandi pecche.
All’inizio del 2000 un altro dispositivo, utilizzato quasi da tutti e
quotidianamente, prendeva vita come console di gioco portatile: il cellulare. Il
rilascio del Nokia N-Gage, nel 2003, stabilì un punto di contatto tra la telefonia
cellulare e le console portatili. La Nokia, combinando la popolarità dei cellulari a
quella che avevano ottenuto le console portatili, come il GameBoy, ha creato un
unico dispositivo che permette di ottenere tutte le caratteristiche di un cellulare,
quasi di un palmare, e quelle oramai necessarie per una console portatile, come il
gioco in multiplayer senza ausilio di fili o la grafica a colori e, in alcuni giochi,
tridimensionale. Il successo non è stato però quello sperato e così la casa
finlandese e molte altre sue concorrenti hanno cercato di utilizzare comunque i
suoi altri modelli di telefonini e gli smartphone come punto di incontro tra
l’industria mobile e quella videoludica.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
13
2.3 - Analisi comparativa
Avendo dato uno sguardo alle piattaforme esistenti e ai loro maggiori pregi e
difetti, è doveroso fare un’analisi comparativa tra le console e gli smartphone,
riassumendone le caratteristiche tecniche.
-
Milton-Bradley Microvision -
La prima console rilevante da analizzare è quella che per prima permise di avere
una interfaccia diversa per ogni tipo di gioco. Ciò era
possibile grazie all’interscambiabilità della parte
frontale della console stessa. Questo piccolo gioiello di
elettronica permetteva di giocare con giochi di bassa
qualità su uno schermo di piccole dimensioni e
utilizzando poche risorse di memoria, anche se allora
potevano apparire come una ingente richiesta di
hardware, utili solo al caricamento di uno tra gli undici
giochi disponibili.
Figura 6 – MB Microvision
Anno:
1979
CPU:
Texas TMS 1100 a 100 KhZ (4bits) o Signetics 8021 (8bits)
RAM:
8 blocchi di 4 bits
ROM:
2 Kilobits
Schermo:
LCD 16x16 - bianco e nero
Suoni:
bip hardware
Dimensioni: 24.5x9.1x4.6 cm
-
Atari Cosmos -
Un altro passo importante nel campo delle console portatili fu indubbiamente
fatto dalla Atari con il tentativo di introdurre la terza dimensione, seppure
simulata per via semi-olografica. Le due luci interne si alternavano mostrando
prima un ologramma e poi l’altro, da differenti angolazioni e i venti LED
presenti permettevano lo svolgimento del gioco. Nonostante questa
particolarità e la presenza di 8 differenti giochi, la console non ebbe molto
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
14
successo, sia per la grafica poco accattivante sia
per il fatto che in realtà, seppure il filo fornito
con essa fosse di dimensioni agevoli, la console
era funzionante solo con la corrente elettrica e
non a batterie.
Anno:
1981
CPU:
COPS411
RAM:
-
ROM:
-
Schermo:
Led dietro schermi olografici
Suoni:
-
Figura 7 – Atari Cosmos
Dimensioni: -
-
Nintendo Game Boy –
Una tra le prime console che, con il solo utilizzo di
quattro batterie stilo, permetteva un ricambio con
migliaia di giochi diversi, il Game Boy è
sicuramente un punto fermo da analizzare se si ci
riferisce al mondo delle console portatili, in quanto è
stata quella più venduta di tutti i tempi. Le
evoluzioni di questa console si riescono ancora a
contare sulle dita di una mano, ma il vero fatto
sensazionale è la retrocompatibilità con tutte le
versioni precedenti.
Questa console, mantenendo la caratteristica croce
direzionale, inventata già per i predecessori Game &
Watch, sempre di casa Nintendo, si è evoluta prima
con speaker più potenti (Game Boy It Loud!), poi si è
chiaramente ridotta nelle dimensioni, seguendo le
Figura 8 - Nintendo Game Boy
riduzioni dei chip esistenti, con il Game Boy Pocket,
successivamente ha acquisito più luminosità, con lo schermo retroproiettato del
Game Boy Light. La successiva console a colori, Game Boy Color, e il suo
successore, il Game Boy Advance, guadagnano anche in processore e memoria
e una porta ad infrarossi per le partite multigiocatore. Il Game Boy SP e il Game
Boy Micro, l’ultima modello, hanno mantenuto grosso modo le stesse
caratteristiche della versione Advance, riducendone però le dimensioni.
La serie di accessori disponibile ha reso questa console uno strumento di
successo completo.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
15
Anno:
1989
CPU:
Custom 8-bit Sharp Z80 a 4.194304 MHz
RAM:
8 kByte S-RAM interna
ROM:
cartucce da 256 kbit a 8 Mbit
Schermo:
160x144
Suoni:
4 canali
Dimensioni: -
-
Sega Game Gear –
Questa
console,
creata
per
contrastare il successo avuto
dall’antagonista Nintendo, non ha
ottenuto il successo sperato.
Nonostante lo schermo a colori,
grande carenza del Game Boy nel
medesimo periodo, la possibilità di
usufruire di moltissimi giochi, già
titoli famosi per le console fisse di
successo di casa Sega, e quella di
poterla trasformare in un piccolo
televisore portatile, non riuscì a
Figura 9 – Sega Game Gear
sbaragliare la casa avversaria. La
durata delle batterie, essendo
veramente ridotta, risultò la caratteristica predominante che ne segnò la disfatta
sul mercato.
Anno:
1989
CPU:
Zilog Z80 (8-bit a 3.6 MHz)
RAM:
16 kByte
ROM:
8 kByte
Schermo:
160x146 a 4096 colori
Suoni:
4 canali
Dimensioni: 11.1x20.7x2.7 cm
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
16
-
Bandai Tamagotchi –
Questo piccolo dispositivo, pur non permettendo il cambiamento del gioco
come invece era possibile per le console
presentate in precedenza, ha rappresentato un
altro ‘boom’ sul mercato dei videogiochi, in
quanto, la crescita di un cucciolo, anche se non
bellissimo graficamente, poneva il giocatore in
uno stato di sfida contro il tempo e con se
stesso per verificare le proprie abilità in qualità
di “pseudo-genitore”. L’alto grado di
giocabilità, racchiuso in soli tre tasti, e il
Figura 20 – Bandai Tamagotchi
successo ottenuto, già garantito dalle sole
Connexion
acquirenti di sesso femminile, ne hanno
permesso parecchie evoluzioni, sia nella terra del Sol Levante, che nel resto del
mondo.
Anno:
1996
CPU:
-
RAM:
-
ROM:
-
Schermo:
3.0x3.0 cm
Suoni:
bip hardware
Dimensioni: 5.9x4.8x1.7 cm
-
Nintendo NintendoDS –
Quest’ultima console di casa Nintendo
dovrebbe sostituire definitivamente il
precedente Game Boy, sia per la sua
retrocompatibilità, seppure solo per i
giochi della versione Advance, sia per
il suo doppio schermo, di cui uno
touch-screen,
che
permette
di
introdurre un elemento di novità che
manca nelle restanti console presenti
sul mercato.
Figura 31 – Nintendo DS
In una veste del tutto rinnovata e con
un doppio processore e un salto in
avanti nell’utilizzo del suono, con
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
17
speaker Dolby Surround, questa console è la degna erede della console più venduta
al mondo, anche se per motivi inspiegabili, il tanto atteso successo non si è
ancora verificato, nonostante l’introduzione della grafica e dell’audio
tridimensionale siano un aspetto nuovo ed oramai molto importante nel campo
dei videogames.
Anno:
2004
CPU:
un ARM9 e un ARM7
RAM:
-
ROM:
-
Schermo:
TFT retroilluminato 256x192 a 260.000 colori
Suoni:
stereo surround
Dimensioni: 8.46x14.86x2.87 cm
-
Sony PSP –
Sony, come Sega ai tempi del Game
Boy, punta su questa console per
sbaragliare l’avversario Nintendo.
Completa in molti suoi punti,
questa console, da poco uscita in
Italia, sta già avendo molto
successo, forse per il fatto che la
casa produttrice è la più affermata
per le console da tavolo.
Le dimensioni imponenti dello
schermo di questa piccola console
garantiscono
un’
immersività
Figura 42 – Sony PSP
maggiore del giocatore nel suo
videogame e permettono inoltre una novità, che la casa sta già sfruttando al
meglio: la possibilità di vedere dei film con la qualità dei supporti DVD.
Anno:
2005
CPU:
333 Mhz
RAM:
32 Mb
ROM:
4 Mb
Schermo:
TFT retroilluminato 480x272
Suoni:
stereo 16 bit
Dimensioni: 17.0x7.4x2.3 cm
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
18
-
Nokia N-Gage –
La casa finlandese ha provato ad entrare nel mondo delle console portatili
creando un dispositivo ibrido, a metà tra un telefono cellulare e una piattaforma
di gioco. Questo cellulare, perché in definitiva questa è la caratteristica
predominante che manca nelle altre console, permette l’utilizzo di una semplice
grafica tridimensionale, sfruttando solamente un processore ARM4 e l’audio in
modalità stereo.
Figura 53 – Nokia N-Gage QD
Questo modello, che non ha rappresentato il
successo che la casa aveva preventivato, ha a
disposizione una moltitudine di titoli e una
community dedicata ai soli possessori del
cellulare stesso. La scarsa popolarità è anche
forse dovuta al fatto che alcuni ignoti hanno
velocemente distribuito tramite internet alcuni
software per utilizzare gli stessi giochi del NGage su altri smartphone della stessa marca.
Anno:
2003
CPU:
ARM4
RAM:
32 a 128 Mb
ROM:
3,4 Mb
Schermo:
176x208 a 4096 colori
Suoni:
stereo
Dimensioni: 11.8x6.8x2.2 cm
2.4 -
Il cellulare – telefono e piattaforma ludica
Sono passati trent’anni circa dall’invenzione del telefono cellulare, solo una
ventina dall’uscita sul mercato del primo modello e quindi dalla sua vera
nascita, con l’idea che ognuno di noi potesse essere raggiungibile ovunque e in
qualsiasi momento. Solo poco più di una decina di anni fa, nel 1992, nasceva il
primo cellulare smartphone, un modello di cellulare a cui vengono aggiunte
delle funzionalità tipiche dei palmari, incorporando così rubrica, orologio,
calcolatore, blocco-note, e-mail (dati reperiti da TorinoScienza.it).
Negli ultimi anni gli smartphone stanno conquistando quote sempre maggiori
del mercato della telefonia mobile, raddoppiando quasi fra il 2004 ed il 2005
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
19
(più di 12 milioni di apparecchi venduti nell'ultimo anno). Si prevede che entro
un paio d'anni la maggior parte dei telefoni venduti avranno a bordo funzioni
considerabili smart, ovvero tipiche di altri dispositivi quali i palmari.
I sistemi operativi più usati per gli smartphone sono Symbian, Palm OS
(sviluppato dalla PalmSource), Windows CE (Microsoft), BREW (Qualcomm) e
Linux. Symbian è oggi il più diffuso, con l'80% installato su cinque diverse
piattaforme, tre delle quali sviluppate da Nokia, (Serie 60, 80, 90), una quarta da
NTT DoCoMo per il mercato giapponese, e la quinta dalla UIQ (dati tratti da
Symbian.com).
Mentre negli USA gli smartphone tendono ad essere PDA a cui si aggiungono
funzioni di telefono, in Europa e Giappone, al contrario, sono telefoni con
aggiunta di funzioni di PDA. Sono quasi sempre inclusi l'accesso a internet, le
email, la pianificazione delle attività (scheduler), la fotocamera, rubrica e contatti
personali. Su alcuni modelli sono disponibili la navigazione satellitare con GPS
e la compatibilità con i più comuni formati di file, come PDF e quelli della suite
Microsoft Office. Si prevede che anche la televisione verrà in futuro incorporata
(la cosa è attualmente in discussione). A tutto questo bisogna aggiungere la
presenza oramai costante dei giochi all’interno di questi dispositivi.
Il fattore chiave di uno smartphone è che si possono installare applicazioni su di
esso, anche di terze parti, il tutto in pochi semplici passi.
I giochi a quanto pare sono la prossima grande onda che trascinerà la crescita
delle comunicazioni cellulari, un settore che, per molti analisti, è molto vicino al
punto di saturazione per quanto concerne i servizi tradizionali.
A livello mondiale il fatturato dei mobile games viene stimato intorno ai 2,6
miliardi di dollari, con una crescita prevista fino al raggiungimento degli 11,2
milardi di dollari per il 2010. Sono passati molti anni da quando nel 1997 fece la
sua comparsa Snake, il primo gioco su cellulare. Da allora il ritmo del mobile
gaming è stato incalzante e già quest’anno, il 2005, può essere definito come
l’anno zero in cui si avrà la comparsa dei primi giochi tridimensionali, con
cellulari che hanno capacità grafiche delle console fisse di videogiochi di
qualche anno fa (vedi Sony PlayStation) e con gli sviluppatori che iniziano
davvero a sfruttarle (dati tratti da WirelessGaming.it ).
Non sono solo i dispositivi che cambiano: anche il pubblico è in fase di
cambiamenti. Un semplice esempio, che distrugge il clichè del giocattolo per
adolescenti maschi ed è in contrasto con la famosa ideologia della “sindome di
Peter Pan”, è che nel corso del primo trimestre del 2005 le donne hanno
scaricato più giochi per i propri cellulari dei compagni maschi.
Il cambiamento interessa anche il mercato che si è abbastanza sviluppato in
modo da essere segmentabile in tre ambiti principali, con caratteristiche e
dinamiche differenti.
Partendo da quello più ampio per numero di potenziali fruitori, il casual gaming,
ovvero quella modalità di gioco che include l’occasionalità del divertimento
ludico, viene visto come terreno di caccia soprattutto dai publisher di giochi, che
puntano a conquistarlo con prodotti semplici e a basse esigenze di manualità, i
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
20
cosiddetti giochi one-touch, con costi bassi ma replicati in un numero
elevatissimo di copie.
Il secondo settore è quello delle communities, un termine che copre un mondo
molto variegato e fenomeni che possono essere favoriti da gestori mobili ed
essere da questi indipendenti. Le comunità di giocatori mobili comprendono di
solito un portafoglio di giochi scaricabili, la possibilità di inviare le proprie
recensioni o di partecipare a tornei virtuali con l’assegnazione di “punti”
spendibili per scaricare ulteriori videogiochi. Queste comunità sono e saranno
sponsorizzate ed appoggiate dai gestori perché, oltre a fidelizzare l’utenza ed
incrementare il traffico dei dati, consente ai gestori stessi di mantenere i
publisher di giochi legati a sé, grazie al ricco mercato potenziale che sono in
grado di offrire. La community, di questo tipo, più grande al mondo è la Game
Lobby, legata al gestore americano Sprint, che conta più di mezzo milione di
iscritti.
« Il rapporto tra gestori mobili da una parte e tutti gli attori di questo mercato
dall’altra sono la grande incognita dello sviluppo » sottolinea Fabio Viola,
direttore responsabile di “Giocare con il Cellulare”, mensile italiano
specializzato nel settore « il modello di business oggi dominante almeno in
Europa vede al centro i gestori, che controllano la base clienti, e tutti gli altri,
dai produttori di handset ai publisher di contenuti, a ruotare attorno con una
quota parte del fatturato globale generato dai giochi inferiore al 20 per cento ».
Nel futuro la situazione potrebbe estremizzarsi: « Con la riduzione a
commodity della voce » conferma Viola « le previsioni danno per il 2009 la
percentuale dell’ARPU (Average Revenue Per User) degli operatori derivante
dai contenuti mobili al 40 per cento. Se si incrocia questa previsione con quella
che assegna gli 11,2 miliardi di dollari generati dal mobile gaming per due terzi al
download e il restante al traffico dei giochi multiplayer e di community, si
comprende che a parità di modello di business il gaming sarà la manna degli
operatori ».
Non è comunque detto che il modello imperante oggi lo sia ancora tra qualche
anno. Se si esamina infatti il terzo segmento del settore, quello dei veri
giocatori, ci si trova davanti a prodotti che già oggi possiedono una grafica di
notevole qualità, raggiungendo quindi dimensioni, al donwload, di circa 1,5Mb.
Lo sforzo e gli investimenti che sono necessari per sviluppare questi giochi, da
una parte, e quello necessario per produrre handset con le funzionalità minime
per farli funzionare, dall’altra, fanno esigere, da parte dei publisher e anche dei
produttori di hardware, un flusso più consistente dell’attuale di entrate e
soprattutto più sicuro ed indipendente dalle scelte dei gestori. Negli Stati Uniti
difatti, la tendenza si stà già manifestando, con i publisher alla ricerca di canali
alternativi per la vendita dei propri giochi, dagli accordi con i produttori di
handset a quelli con le catene di sale giochi.
I videogames oggi concepiti per coloro che vogliono solamente giocare, saranno
d’altra parte un giorno anche per i giocatori casuali. La parola d’ordine è infatti
integrazione dei contenuti, con grafica tridimensionale, streaming audio,
messaggistica e possibilità di effettuare download.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
21
Oltre ai giochi si stanno sviluppando una sorta di “ambienti mobile” interattivi
di socializzazione. Questi ambienti sono il corollario di intrattenimento ideale
per “oggetti” che non sono più solamente dei telefoni cellulari, ovvero quelli
che erano stati definiti apparecchi cellulari con funzionalità aggiunte, ma
diventano veri e propri device tecnologici personali e allo stesso tempo
universali.
Basta, difatti, scorrere le funzioni del cellulare del futuro, delineati dal recente
studio della inglese Impaq sulla mobile life. A fronte di cose come la telefonia, gli
SMS, le foto e al massimo l’utilizzo dei portali degli operatori, il cellulare del
futuro farà, tra le altre cose, il pagamento dei parchimetri, sostituirà le carte
fedeltà e in seguito anche quelle di credito o debito, permetterà il check-in dei
voli, il pagamento presso distributori automatici, del conto alla spesa al
supermercato e farà persino da chiave elettronica o telecomando.
Risulta chiaro che nessuno più affiderebbe tutte queste funzioni ad un oggetto
che è in possesso di un singolo gestore di telecomunicazioni.
Non bisogna comunque correre così avanti nel futuro per ipotizzare di vedere
qualcosa di quanto è stato citato. Basti pensare che qualche tempo fa Mediaset e
Tim hanno raggiunto un accordo che pone le basi per il lancio commerciale in
Italia, come primo paese al mondo, della TV sul telefono cellulare in digitale
terrestre con la tecnologia DVBH, ovvero Digital Video Broadcast Handheld
(dati reperiti da TlcWorld.net, Ott 2005).
Lo sguardo al futuro non deve essere neanche molto penetrante per quanto
riguarda il ruolo dei giochi tridimensionali sui telefoni cellulari. Se è vero,
infatti, che nel 2005 hanno iniziato a fare la loro comparsa i primi giochi con
grafica di buon livello tridimensionale, non c’è da stupirsi che il settore dei
costruttori dei telefoni cellulari
si impegni ad attrezzare i loro
dispositivi di acceleratori grafici
o altri chip dedicati, come
successo per i nuovi modelli
SPH-G1000 e SCHG100 di casa
Samsung o i nuovi LG SV360 e
KV3600 della Logitech, capaci
di elaborare un milione di
poligoni al secondo (dati tratti
da WirelessGaming.it).
Figura 64 – LG KV3600
2.5 -
Uno sguardo al futuro
Il cellulare del futuro perderà le funzionalità della telefonia o rimarranno anche
queste insieme alla moltitudine di prestazioni aggiuntive che verranno
effettuate? A questo grande dilemma, in realtà, la risposta è più che ovvia: il
cellulare avrà sempre la sua funzione di telefono portatile. E’ interessante
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
22
invece provare ad elencare quali sono le ultime innovazioni nel campo e quali
saranno i suoi sviluppi futuri.
La Texas Instruments ha da poco svelato il suo
lavoro in questa direzione e la creazione di una
nuova generazione di chip per telefoni cellulari che
porterà in un palmo di mano audio e video di altà
qualità e prestazioni grafiche tridimensionali sempre
più all’avanguardia. La creazione della nuova
generazione dei processori OMAP (Open Multimedia
Applications Protocol), che si avvalgono di un nuovo
processo di produzione a 90 nanometri per ospitare
un maggior numero di transistor e di funzionalità, è
Figura 74 – Futuremark
un altro segreto svelato dalla stessa casa americana.
SPMark04
Questa nuova architettura supporta fotocamere
digitali con più di 4 megapixel, giochi 3D interattivi,
videocamere digitali, TV e riproduzione di filmati ad alta definizione (dati:
PuntoInformatico.it, Feb 2005).
Questa nuova generazione di processori che includono anche alcuni Digital
Signal Processor per audio e video, sarà in grado di spingere le prestazioni video
di 4 volte rispetto a quelle attuali e quelle dei giochi tridimensionali fino a 40
volte, permettendo così di riprodurre giochi con un numero di poligoni
nettamente superiore a quello che caratterizzava i titoli della PlayStation, di
casa Sony: si parla di circa 2 milioni di poligoni al secondo.
La generazione successiva di processori dedicati ai telefoni cellulari consentirà
inoltre di applicare effetti 3D all’audio di qualità Hi-Fi, ricevere segnali TV
analogici e digitali, comunicare via wireless ad alta velocità e di utilizzare display
con risoluzioni maggiori di quelle della classica VGA (640x480) e fotocamere
con risoluzioni fino a 6 megapixel.
A queste prestazioni vanno
aggiunte inoltre lo sviluppo di
system-on-chip che integrano,
in un unico pezzo di silicio,
tutte le principali funzionalità
di un dispositivo mobile,
come la gestione dell’energia,
lo stack dei protocolli per le
comunicazioni wireless, la
gestione della banda radio
base e della frequenza o il
controllo per l’accessio alla
memoria
embedded,
consentendo in tal modo ai
produttori di continuare a
realizzare dispositivi compatti
e leggeri e, soprattutto, di
contenere i costi di produzione.
Figura 84 – Smartphone features (Q3 2005)
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
23
3 Tamagotchi – un caso di studio e un punto di partenza
3.1 -
Storia
Il Tamagotchi, inventato da Aki Maita, prodotto dall’azienda di giocattoli
Bandai e messo in commercio sin nel 1996, divenne subito un gioco di successo,
tanto che alla fine del 1997, solo in Giappone, la ditta
aveva già venduto 15 milioni di pezzi. Come già
accennato precedentemente, questo prodotto ebbe un
successo strepitoso soprattutto tra utenti di sesso
femminile. Le donne di tutte le età, dalle bambine di
scuola elementare alle impiegate e alle casalinghe,
divennero quindi le fans più accanite del miniFigura 15 - Bandai
prodotto. Grazie ad un’opera di esportazione, il
Tamagotchi Connection
Tamagotchi ha poi spopolato negli USA e quindi
anche in Italia e in tutta Europa, fino a raggiungere la quota di 40 milioni di
pezzi venduti, di cui 20 milioni solo negli USA e nel Canada e 600 mila in Italia
(da AnimeFringe.com, Ott 2004).
Cosa ha catturato l’attenzione di grandi e piccini e quindi cos’è in realtà il
Tamagotchi? Questo prodotto non è altro che
un gioco di simulazione, abbastanza piccolo, a
forma di uovo, con schermo a cristalli liquidi,
che rappresenta vari tipi di animali in
differenti stati di crescita; il gioco consiste
nell'allevare questi animali a partire dallo stato
pre-natale, dentro l'uovo. Il vero segreto della
popolarità del Tamagotchi è la situazione di
sfida che si crea a seconda delle necessità che
questi cuccioli virtuali manifestano. Infatti se
non ci si prende cura del proprio cucciolo nel
modo giusto, questo comincerà a piangere per
attirare l’attenzione verso di sè. Inoltre,
bisogna considerare il fattore notevole di
autostima e di gratificazione personale del Figura 26 - Tamagotchi possibilità di
evoluzione
giocatore che si manifesta se il proprio cucciolo
è ben curato e viene ben allevato.
Fin dalla prima versione del Tamagotchi erano state annunciate future release,
che avrebbero portato innovazioni e cambiamenti, ognuno con un intero set di
personaggi. Primo tra essi il Tamagotchi Angel, che permetteva al giocatore di
prendersi cura dei propri cuccioli virtuali ritornati dal loro pianeta natale.
Successivamente fu prodotto il Tamagotchi Ocean, rilasciato però solo in
Giappone, che come suggerisce il nome, permetteva di allevare dei personaggi
del mare, come Osutchi & Mesutchi, personaggi famosi in Oriente. Ultima
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
24
versione rilasciata fu il Tamagotchi Forest che era una release abbastanza
complessa da giardino dotata di sensori di movimento.
Nel 2004, quando quasi tutti avevano dimenticato l’esistenza del pulcino
virtuale e delle sue esigenze, la casa giapponese ha sviluppato e messo sul
mercato una nuova versione. Questo nuovo Tamagotchi è fornito di una porta a
infrarossi per comunicare con i suoi simili, accoppiarsi e generare quindi quello
che è stato chiamato “Tamababy”, ovvero un mini-mini cucciolo.
Torna quindi l’amatissimo pulcino virtuale, che già costituì un successo a livello
planetario, che fu però, a dire il vero, protagonista di accesi dibattiti tra
associazioni di genitori, psicologi e studiosi di pedagogia, indecisi sulla sua
valenza educativa nei confronti dei fruitori più giovani. Mentre nella terra del
Sol Levante si permetteva di far nascere asili a pagamento preposti solamente
alla cura delle creature virtuali, in Europa si rischiò più volte il ritiro dal
mercato.
Sostanzialmente immutato esteticamente, se non per il design poco più
innovativo e qualche decorazione aggiuntiva, il portachiavi a forma di uovo, l’
amatissimo Tamagotchi “Connexion”, disponibile in Giappone già dal marzo
2004, si rivela adeguato alle attuali potenzialità tecnologiche, integrando una
porta ad infrarossi che lo rende capace di connessioni remote con i suoi simili.
Un accorgimento che obbliga l’ignaro acquirente, oltre che a nutrire, pulire,
curare e far divertire il piccolo cucciolo elettronico, a rendersi responsabile
anche della sua vita sociale. Il nuovo Tamagotchi difatti necessita di amici e,
soprattutto, di incontrare un compagno di sesso opposto a scopo riproduttivo.
Se tutto andrà per il verso giusto, l’utente assisterà alla felice nascita del
“Tamababy”, un’ulteriore fonte quindi di ansiose responsabilità simulate.
Certo il mercato del Tamagochi non ha avuto lo stesso impatto che ebbe al suo
primo rilascio, ma il successo non è mancato. Se si pensa inoltre che il guadagno
è per lo meno raddoppiato, visto che qui in Italia nel 1997 il Tamagotchi costava
24.900 lire e oggi la nuova versione viene venduta a 24,90 euro.
All’atto del rilascio del Tamagotchi in versione
portatile, chiaramente nacquero anche versioni
dedicate per tutte le console, dal PC al GameBoy, e
tutta una serie di gadgets inevitabili, divenuti
anche parte in regalo dell’Happy Meal della linea
McDonald’s.
Bisogna aggiungere che al rilascio del Tamagotchi
sono seguite una serie di manie dedicate al
cucciolo virtuale e quindi sono nati siti web
dedicati all’argomento, di community di fans e di
quelle che vengono chiamate Fan Fiction, ovvero
Figura 37 - Tamagotchi per
Game Boy Advance
storie inventate dai fans su un argomento
particolare del mondo del Tamagotchi, ad esempio sulla provenienza dei loro
cuccioli, su come si sono innamorati, come vivono le loro giornate, come
salvano l’universo e altre invenzioni simili. Oltre a ciò, che in realtà non è altro
che la dedizione dei fan, si è sviluppata tutta una serie di prodotti di case
concorrenti che hanno cercato di imitare il prodotto originale, spesso senza
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
25
alcuna aggiunta o miglioramento rispetto all’originale, ma solo con un
sostanziale risparmio nel prezzo.
3.2 - Analisi del prodotto
In questo paragrafo si illustrerà il funzionamento di questo dispositivo e il gioco
al suo interno, quali opportunità offre al giocatore e le sue caratteristiche
tecniche. Il Tamagotchi analizzato è la seconda versione e dispone della
possibilità di far interagire il proprio cucciolo con quello di altre persone.
Il Tamagotchi Connexion è un cucciolo virtuale che si evolve in maniera
differente a seconda delle attenzioni che gli vengono prestate. Scopo del gioco è
quindi divertirsi con il cucciolo, dargli da mangiare, curarlo in caso di malattia e
fargli fare nuove conoscenze. Con questa versione del Tamagotchi è quindi
possibile comunicare con nuovi amici e salvare una lista di massimo 50 altri
cuccioli, giocare con loro e scambiarsi dei piccoli regali fino a trovare l’anima
gemella con cui far nascere un nuovo pulcino.
Per iniziare a giocare per la prima volta bisogna aspettare che l’uovo che
compare sullo schermo si schiuda. Si ha quindi il tempo di inserire l’ora attuale,
la data e il nome che si vuole dare al proprio cucciolo. Dopo all’incirca un
minuto l’uovo si schiude e si scopre anche se il proprio cucciolo è maschio o
femmina. Esistono diverse fasi di sviluppo del cucciolo: uovo, bebè, bambino,
ragazzo e adulto; ognuno di esse corrisponde ad un modello differente di
cucciolo.
Per far crescere il proprio cucciolo bisogna innanzitutto nutrirlo. Quando il
Tamagotchi ha bisogno di qualcosa emette quindi un segnale sonoro e si
illumina l’icona dell’Attenzione: bisogna controllare se il cucciolo abbia voglia
di mangiare o se sia solo uno schiamazzo momentaneo e quindi indice di poca
disciplina. Alcuni indicatori permettono di capire come il cucciolo stia
crescendo. Sono presenti indicatori per il livello di fame o di felicità del
cucciolo, un altro per la sua disciplina, uno per la lista di amici e il grado del
legame e una scheda che mostra età, peso, nome, sesso e generazione del
Tamagotchi.
Le azioni da compiere con i tre tasti presenti sul dispositivo sono: dargli da
mangiare, quindi scegliere se è solo l’ora per uno spuntino o se si vuole
cucinare un buon pranzetto per il proprio cucciolo, pulirlo, si vedrà quindi un
getto d’acqua inondare lo schermo e poi andare via, giocare insieme, scegliere
quindi di farlo ballare o semplicemente farlo saltare su se stesso, curarlo, per
dargli una buona dose di medicina e rimetterlo in sesto, nel caso in cui potesse
star male, spegnergli la luce, per farlo addormentare, o infine farli un piccolo
regalo.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
26
Usando i sensori a raggi infrarossi presenti
nel dispositivo si può far comunicare un
Tamagotchi con un altro e permettergli di
effettuare alcune azioni. Una volta stabilita
la connessione, i due cuccioli si possono
scambiare dei regali o giocare insieme a due
differenti giochi: chi gonfia un palloncino
per primo o chi finisce per primo il proprio
cibo,
vince.
Stabilendo
spesso
la Figura 48 – Dispositivo IRDA del Bandai
connessione con gli stessi cuccioli, un
Tamagotchi Connection
Tamagotchi può diventare il compagno
vero e proprio di un altro e instaurare così una relazione sentimentale per far
poi nascere un cucciolo. Se questo dovesse accadere, dopo alcuni momenti in
cui genitore e figlio convivono nello stesso spazio, il padre cede lo schermo al
figlio e quindi il gioco è destinato a ricominciare.
Bisogna considerare un ottimo aspetto di questo prodotto: se il proprio cucciolo
non viene ben allevato ovvero è gestito in maniera errata, l’aspetto del cucciolo
ne risentirà, subendo delle deformazioni e quindi anche i suoi incontri
potrebbero essere infruttuosi dal punto di vista sentimentale.
Il dispositivo è alto all’incirca 6 cm, largo 5 cm e spesso quasi 2 cm; è dotato di
tre pulsanti frontali ed uno posteriore, ognuno con una funzione dedicata: il
primo serve per selezionare le differenti opzioni, il secondo per confermare una
scelta e il terzo per annullarla, mentre il pulsante sul retro serve per resettare la
memoria e ricominciare da capo. Lo schermo ha dimensioni abbastanza ridotte,
un quadrato di poco meno di 3 cm per lato; se si pensa inoltre che nella parte
superiore e inferiore dello stesso si presentano due barre di circa 0,5 cm il
display si riduce ancora notevolmente. Esistono differenti design del
Tamagotchi, ma le caratteristiche sono sempre le stesse. Bisogna aggiungere la
presenza nella parte superiore del dispositivo del sensore e dell’attuatore ad
infrarossi che serve per far comunicare cuccioli differenti.
3.3 -
Evoluzione e sviluppi futuri
Come sarà il Tamagotchi del futuro? A colori, è la prima risposta che si
potrebbe dare, ma ancora più immediato è il rinvio alla tecnologia
tridimensionale e quindi si pensa che presto vedremo nel mercato mondiale
una versione 3D del famoso gioco per grandi e piccini.
Un’evoluzione grafica quindi sarebbe sicuramente un primo passo per
migliorare l’estetica e la giocabilità del prodotto e per non rimanere indietro
rispetto alla concorrenza; difatti se si pensa che Nintendo ha da pochi mesi
rilasciato, in America, una propria rivisitata versione tridimensionale, curata nei
minimi dettagli e tale da suscitare quella tenerezza nascosta anche nei cuori di
pietra, del famoso videogame della casa Bandai, soprannominata NintenDogs, da
cui facilmente si può intendere che i protagonisti di questo prodotto sono dei
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
27
cuccioli di cane, sicuramente i possessori della console NintendoDS avranno
abbandonato i loro Tamagotchi per correre ad accaparrarsi una copia del nuovo
videogame.
Con la presenza della grafica
tridimensionale, l’interazione
potrebbe diventare quindi
molto
più
interessante.
Ancora una volta se si torna
ad osservare quante sono le
novità inserite nel prodotto
della Nintendo, non si capisce
perché il nuovo Tamagotchi
non dovrebbe poter sfruttare
queste potenzialità, tra cui ad
esempio il fatto di poter
accarezzare e coccolare il
proprio cucciolo, giocare con
Figura 59 – NintenDogs per Nintendo DS
lui in ambienti tridimensionali
e quindi permettergli di muoversi nelle tre dimensioni dello spazio, portarlo
fuori casa, a passeggiare, a comprargli dei vestitini o dei gadgets per abbellirlo
o ancora portarlo a giocare con altri esemplari.
Certo si potrebbe anche pensare ad una versione olografica di questo
videogames, visto che le animazioni sono tutte pre-salvate e solamente
riprodotte, ma si perderebbe l’opportunità data dalla interazione di creare
momenti imprevisti, con atteggiamenti nuovi e diversi.
Oltre all’aggiunta sicuramente oramai necessaria della terza dimensione, si
pensa che nella futura versione del Tamagotchi si potranno udire dei versi, dei
suoni o della musica, molto più vicini a quelli reali piuttosto che dei semplici
“beep” molto poco attraenti.
Poter scegliere una vasta gamma di cuccioli è un’altra risorsa che manca al
Tamagotchi. Pochi sono i cuccioli differenti e inizialmente risultano tutti molto
somiglianti tra loro. Questa caratteristica dovrebbe permettere di poter
differenziare il proprio virtual pet da quello di un'altra persona.
Da qui nasce la necessità di poter dare un nome al proprio Virtual Pet, e
permettere un processo di speech recognition in modo da poter chiamare il
proprio cucciolo per nome e vederlo così reagire, cosa peraltro già possibile nel
gioco di casa Nintendo.
Una alternativa ancora potrebbe essere quella di utilizzare cuccioli appartenenti
ad ecosistemi differenti, quindi cuccioli marini, come delfini, anfibi o pesci di
altro genere, terrestri, volatili o ancora extraterrestri, come l’originale
Tamagotchi.
Una futura evoluzione del Tamagotchi potrebbe essere quella di permettere al
cucciolo di essere uno strumento, oltre che di divertimento e di svago, anche di
apprendimento e quindi far sì che ci possano essere dei momenti in cui i
cuccioli, dedicati alle differenti fasce di età, potrebbero infondere saggezza
nell’utente medio del videogame.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
28
Una caratteristica importante che per ora ha sempre interessato il Tamagotchi è
quella che insieme al gioco bisogna anche comprare il dispositivo che lo fa
funzionare, come un unico pezzo di fabbrica. Una interessante novità potrebbe
essere quella di sfruttare la tecnologia già presente sul mercato, che ha già
raggiunto livelli tecnologici più alti rispetto al Tamagotchit tradizionale, e
creare videogiochi dedicati a tali dispositivi e quindi riuscire ad effettuare il
porting delle applicazioni per cellulari e altre console portatili o fisse.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
29
4 Tools di sviluppo
Pokémòn Virtual Pet è un’implementazione tridimensionale del famoso
Tamagotchi, destinato ai cellulari Nokia Series60, che sfrutta alcune potenzialità
delle OpenGL ES.
Le funzionalità sono esattamente le stesse del Tamagotchi originale, l’unica
grande differenza è che questa versione sfrutta la grafica tridimensionale e
suoni diversi da semplici bit hardware.
4.1 -
Strumenti grafici e CAD
Per sviluppare questa applicazione sono stati utilizzati differenti tools di
sviluppo, sia per la creazione dei modelli tridimensionali da utilizzare nel
gioco, sia per le immagini e le textures dei modelli, che per lo sviluppo e la fase
di testing.
Analizziamo le varie fasi
di
sviluppo
e
gli
strumenti utilizzati in
ognuna di esse.
Il primo stadio è stato la
creazione dei modelli
tridimensionali. Per fare
ciò è stata utilizzata una
tra
le
più
famose
soluzioni
per
la
creazione, animazione e il
rendering
di
modelli
tridimensionali:
Alias
Maya 6.5.
I modelli sono stati creati
attraverso
la
Figura 20 – Alias Maya 6.5
modellazione poligonale,
utilizzando le immagini di riferimento dei due personaggi del cartone animato,
nonché famoso gioco di carte da tavolo, Pokémòn: Pichu e Pikachu. Lo
strumento utilizzato permette inoltre, una volta creato il modello, di applicare
sulla superficie una texture, ovvero una semplice immagine, e di generare
automaticamente le coordinate UV da utilizzare direttamente nell’applicazione.
La creazione delle texture è stata effettuata con diversi software di grafica
vettoriale e bidimensionale, come Paint, Corel Photo House e Adobe Photoshop
6. Questa fase è iniziata utilizzando il tool di Maya UV Texture Editor che
permette di visualizzare un’anteprima della posizione delle UV e di modificarla
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
30
prima di creare un’immagine che rappresenti quindi i vertici e il lati dei
poligoni. Una volta salvata tale immagine, in cui appare lo sfondo in colore
nero e il poligono disteso e schiacciato in colore bianco, si possono modificare
con un programma di grafica tutte le varie parti del poligono e colorarle con le
appropriate sfumature.
Generati i modelli, per creare l’animazione scheletrica è stato utilizzato il
software MilkShape3D. Per importare i modelli in tale applicazione ci si è
serviti di un tool di conversione dai
file in output di Maya (.mb) in file
formato 3D Studio max (.3ds) . Per
effettuare questa operazione, il
software Deep Exploration è apparso
molto adatto allo scopo, sia perché
con i continui aggiornamenti cerca di
essere sempre il prodotto migliore
sul mercato, sia perché la sua
efficienza in termini di conversione è
veramente eccezionale.
I file convertiti, in modelli formato
Figura 21 – Deep Exploration
3ds, sono stati poi importati nel
programma MilkShape3D per creare l’animazione. La scelta di tale software è
dovuta soprattutto al formato di output (MilkShape3D ASCII File Format), che
permette una lettura semplice, rapida ed intuitiva di tutti i dati necessari
all’applicazione creata. Per creare l’animazione è stato utilizzato uno tra i
metodi più tradizionali. Per prima cosa è stato costruito lo scheletro da
utilizzare insieme al modello, scegliendo un nodo principale e creando quindi
una sorta di albero di derivazioni con tutte le altre ossa. Successivamente, ad
ogni osso sono stati associati i vertici che ognuno di essi doveva influenzare,
traslandoli o ruotandoli. La sequenza di animazione è stata creata utilizzando
una sequenza di keyframe, in cui viene salvata la traslazione e la rotazione di
ogni osso rispetto alla posizione del primo istante, in cui il modello assume la
sua posizione di staticità completa.
Utilizzare
un’
animazione
scheletrica ha permesso di evitare
gran parte delle computazioni
onerose che avrebbe invece
richiesto un morphing effettuato
per ogni vertice, salvando quindi
le differenti posizioni dei vertici
in ogni keyframe.
Ottenuto quindi in output il file
ASCII di MilkShape3D, sono state
create due piccole applicazioni in
C, per riuscire a convertire i dati,
presenti all’interno di tale file, in
Figura 22 – MilkShape3D
codice da inserire direttamente
all’interno del programma. Questi due programmi non fanno altro che generare
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
31
in file distinti i dati relativi alle posizioni dei vertici, delle normali, degli indici
dei vertici di ogni faccia, le coordinate UV di ogni vertice, l’indice dell’osso a cui
ogni vertice è influenzato, la relazione di dipendenza di tutto lo scheletro e i
vari keyframe dell’animazione. Il funzionamento delle due applicazioni è
abbastanza semplice: prendono come input dei file di testo opportunamente
formattati e restituiscono in output uno o due file di testo che contengono il
codice C++ da utilizzare nel programma. I file di input opportunamente
formattati corrispondono in realtà a ciò che si ottiene da una semplice
operazione di “copia e incolla” di alcune parti del file ASCII di MilkShape3D.
Per maggiori informazioni riferirsi all’appendice A.
4.2 -
Linguaggio di programmazione
L’intero progetto è stato creato adoperando il linguaggio C++.
La scelta che inizialmente si presentava era tra i due linguaggi più utilizzati per
sviluppare applicazioni su sistemi embedded e, nello specifico, su cellulari: Java e
C++.
Il linguaggio Java, seppur di ultima generazione e ampiamente documentato
sul World Wide Web, non rappresentava una scelta ottimale del caso, in quanto,
lo sviluppo di applicazioni tridimensionali sarebbe risultato meno performante
e, inoltre, la mancanza di esempi dedicati proprio a questo ambito è un
elemento importante da considerare se si pensa che si è partiti in questa
impresa senza alcuna conoscenza dello sviluppo su sistemi embedded.
Al contrario per il C++, il linguaggio adoperato, la presenza di esempi dedicati
proprio allo sviluppo di applicazioni tridimensionali e all’utilizzo di rendering
di oggetti poligonali e anche a quello delle API OpenGL ES, ha favorito la scelta
in questa direzione.
Con l’utilizzo di questo linguaggio ad oggetti è inoltre possibile adoperare i
puntatori, di cui si fa grande uso nel framework creato, cosa che risulterebbe
impossibile al contrario con il linguaggio Java, che fa a meno dell’utilizzo dei
puntatori stessi.
Utilizzando i diversi esempi e tutorial, forniti con il Software Development Kit di
casa Nokia, è stato inoltre possibile intuire l’utilizzo di alcune librerie, come i
file “e32math.h” e “e32base.h”, che contengono rispettivamente alcune utili
implementazioni matematiche, sicuramente necessarie in un programma che fa
uso pesante della geometria computazionale, e la definizione della classe
‘CBase’, da cui poter derivare le altre del programma, che offre una struttura
adatta all’utilizzo basilare di una classe e all’invocazione dei metodi del sistema
sottostante.
Il linguaggio C è invece stato adoperato per creare due applicazioni, utilizzabili
da riga di comando, che permettono di ottenere il codice riguardante i modelli
tridimensionali da inserire direttamente nei file del progetto dell’applicazione
‘Pokémòn Virutal Pet’.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
32
L’utilizzo di tale linguaggio è stato adoperato per l’alto grado di familiarità
posseduto con esso e anche per la possibilità di effettuare il riuso del codice di
altre applicazioni precedentemente sviluppate, per la gestione dell’input ed
output da file.
4.3 -
Editor
Per
scrivere
l’intero
progetto è stato utilizzato
il programma, di casa
Microsoft, Visual Studio
.Net 2003.
Questo programma non è
solo un semplice editor,
con alcune funzionalità
aggiunte, come il fatto di
evidenziare in maniera
automatica
le
parole
chiave dei vari linguaggi,
C++
compreso
naturalmente, ma ha al
suo
interno
differenti
utilities
tra
cui
un
Figura 23 – Microsoft Visual Studio .Net
compilatore, un debugger, e
molte altre necessarie alla creazione di programmi, progetti, applicazioni con
form grafici o altro ancora.
Gli strumenti adoperati in questo caso si limitano però ai primi nominati,
ovvero l’editor di testo vero e proprio, il compilatore e il debugger.
Una volta creato il progetto con alcuni programmi appositamente forniti con
l’SDK della Nokia, o più semplicemente ottenuti modificando in maniera
adeguata altri progetti preesistenti, il programma permette utilizzando
solamente l’interfaccia grafica, di inserire le librerie necessarie, indicare quali
sono le directory in cui si posizioneranno i file creati, sia i file .cpp che quelli .h,
dove e se creare un file che sia eseguibile o utilizzabile da altri programmi,
rappresentato, in questo caso specifico, dall’emulatore del cellulare.
È inoltre possibile settare altri numerosi parametri destinati al compilatore, già
compreso nel programma, tra cui il livello di warning di cui si vuole essere
avvisati, quali ottimizzazioni si vogliono effettuare durante la compilazione e
quali definizioni si devono passare al preprocessore, per far sì che vengano
attivate alcune parti di codice al posto di altre, attraverso semplici controlli.
Il debugger fornito con l’applicazione è sicuramente performante in quanto molti
degli errori, banalmente creati per disattenzione o sviste, sono stati risolti
proprio grazie a questo strumento.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
33
Con questo non si può comunque affermare che tale utility sia perfetta e priva
di errori, in quanto le indicazioni fornite, non sono sempre sufficienti a
segnalare da cosa sia causato il crash dell’applicazione creata.
4.4 -
Suoni e audio
L’utilizzo di una colonna sonora come sottofondo al videogioco e la fruizione di
suoni che riproducessero i versi del cucciolo virtuale è stata resa possibile, non
solo dalla presenza in rete di alcune registrazioni audio dei versi di alcuni
Pokémòn e di altri personaggi dell’omonimo cartone, ma anche da alcuni
particolari strumenti.
Alcune registrazioni sono state effettuate per mezzo di un dispositivo portatile,
un mp3 player, dotato anche di un microfono di buona qualità. Con questo
dispositivo è possibile registrare suoni e rumori dall’ambiente circostante, ed
effettuare registrazioni di buona durata, cosa che si è resa però non necessaria
in quanto la dimensione dei file audio doveva rimenere comunque ridotta per
evitare di appesantire in modo esagerato l’applicazione creata. Il file si presenta
poi in formato WAV, direttamente all’interno della memoria del dispositivo e
quindi poi facilmente reperbile.
Per apportare alcune modifiche al file è stato adoperato un programma che tutti
gli utilizzatori di Windows posseggono, magari inconsapevolmente, non
avendolo mai sfruttato: il registratore di suoni di Windows.
Con questa semplice utility presente nel sistema Microsoft e pochi click del
mouse è possibile effettuare tagli, modifiche di formato, introdurre alcuni
semplici effetti ed altro ancora. Sembra quasi strano che con questo programma
fruibile a tutti gli utenti di Windows, sia possibile ricreare dei file utilizzabili in
videogames dedicati a dispositivi cellulari.
Adoperando questa utility è stato possibile cambiare in modo opportuno i file
WAV, sia quelli reperiti via Internet, sia quelli ricreati attraverso il metodo
sopra descritto, apportando le seguenti modifiche:
- la velocità in bits è stata settata a 128 kbps
- la dimensione del campione audio a 8 bit ad unico canale
- la velocità del campione audio invece è stata impostata a 16Khz
- il formato audio di compressione utilizzato è stato il PCM.
Queste caratteristiche sono alquanto importanti visto che le librerie fornite con
l’SDK di Nokia permettono la fruizione di file audio di questo tipo ed è quindi
stato possibile farne uso in maniera semplice e veloce anche nell’applicazione
creata.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
34
4.5 -
Nokia Series60 SDK
Per sviluppare l’applicazione è stato utilizzato il Nokia Series60 Software
Development Kit (SDK) per Symbian OS 8.0a, o inferiori, che supportano le
Feature Pack 2. Tale SDK permette la creazione di applicazioni per devices basati
sulla piattaforma Series60 usando come linguaggio di programmazione C++.
Questo SDK contiene tutte le funzionalità chiave necessarie per lo sviluppo
delle applicazioni ( documentazione, riferimento delle API, tools per effettuare
particolari add-on, un emulatore del cellulare e un compilatore ) escludendo
l’IDE, anche se tale mancanza è ovviata dal fatto che sia supportato da
Microsoft Visual Studio 6, Microsoft Visual Studio .Net 2003 Professional e
Borland C++ Builder X 1.5.
La piattaforma Series 60 rappresenta un ricco
ambiente di sviluppo per creare innovative
applicazioni, basate chiaramente sul sistema
operativo Symbian OS, affiancandolo con una
serie di librerie per lo sviluppo di particolari
GUI (Graphical User Interface), con componenti
ed API dedicate all’I/O e a tutte le funzionalità
Figura 24 – Logo piattaforma
Series60
standard delle applicazioni su cellulare di tale
serie ( Bluetooth, Speech Recognition, OpenGL ES, Message Queue, Browser plug-in,
ecc. ).
Questo SDK è disponibile direttamente all’interno del sito web
http://www.forum.nokia.com/, punto di partenza per tutti gli sviluppatori di
applicazioni per cellulari Nokia, ed è comprensivo di alcune applicazioni di
esempio ed accurata documentazione.
Un utile strumento in questo SDK è sicuramente
rappresentato dall’emulatore che funziona sia in
modalità di Debug che Release e che permette di
osservare man mano le modifiche effettuate sulla
propria applicazione senza necessità di dover
continuamente caricare il programma sul cellulare
per testarlo, sebbene le differenze di prestazioni
Figura 25 – Nokia SDK con
siano notevoli in quanto il processore che gestisce
emulatore integrato nell’IDE
tutte le problematiche dell’emulatore non viene
simulato, ma è direttamente quello del computer sul quale si sviluppa
l’applicazione.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
35
4.6 -
Emulatore
Un importante strumento di sviluppo adoperato è senza dubbio l’emulatore
fornito con l’SDK della Nokia.
Questa applicazione crea una serie di sotto-directory, all’interno di quella in cui
viene installato con l’SDK, che riportano in modo similare la struttura che il
sistema Symbian OS ha sui dispositivi cellulari. Questa suddivisione delle
cartelle è importante in quanto la creazione e l’inserimento di immagini, suoni o
altri file, dettata dai programmi creati, permette di capire l’effetto che questi
avranno sul telefono cellulare su cui si effettueranno i testing finali e di intuire
l’importanza della destinazione delle operazioni effettuate.
L’emulatore si presenta graficamente come un
cellulare della “Series60” di casa Nokia e quindi
con tutti i programmi di default installati, la
rubrica e tutte le funzioni del telefono cellulare,
anche se non risulta chiaramente possibile
effettuare telefonate o inviare SMS o MMS. La
tastiera del cellulare virtuale riproduce quella di
un telefonino reale e la pressione dei tasti può
essere comandata sia con l’uso del mouse, che con
specifici tasti della tastiera del computer.
La simulazione del sistema SymbianOS è
altrettanto buona, tanto che l’interfaccia utente
risulta pressoché uguale.
Una caratteristica peculiare è quella che
l’emulatore funziona sia in modalità release che
debug, facendo quindi riferimento anche all’IDE
utilizzato per la programmazione, la compilazione
e il debugging del codice. Un uso appropriato
dell’emulatore permette di capire quali siano i
problemi che si nascondono dietro al crashing del
sistema o solamente dell’applicazione.
Figura 26 – Emulatore fornito
Le indicazioni fornite ancora una volta risultano
con il Nokia SDK
però nella maggior parte dei casi poco utili per
capire dove localizzare l’errore o quale accesso errato alla memoria è stato causa
dell’errata esecuzione.
Risulta inoltre possibile consultare direttamente le guide dedicate alllo
strumento e settare alcune preferenze per quanto concerne la gestione della
capacità della memoria, la modalità debugging, la connessione ad internet, IRDA
o Bluetooth.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
36
4.7 -
Create_PKG e Create_SIS
Due programmi di grande utilizzo e che sono stati una risorsa inevitabile allo
scopo di produrre “Pokémòn Virtual Pet”, sono Create_PKG e Create_SIS. Il
primo permette di compilare il codice scritto e, magari, già testato
sull’emulatore, in un file con estensione .pkg, da cui il nome, che è un vero e
proprio pacchetto contenente tutti i dati dell’applicazione, i file e il necessario
per il funzionamento dell’applicazione, in maniera compressa.
Il secondo programma, lavorando sul file prodotto dal primo, crea un file con
estensione .sis, che è l’eseguibile da installare sui telefoni cellulari della
Series60. Questo file contiene in pratica l’applicazione di installazione e il
pacchetto da installare. Al momento dell’apertura di tale file su un telefono
cellulare, in pochi e semplici passaggi, i file, compreso l’eseguibile
dell’applicazione creata, con estensione .app, vengono estratti nelle appropriate
cartelle, settate al momento della creazione del pacchetto, e l’applicazione, se
l’installazione non restituisce alcun errore, risulterà installata e funzionante.
4.8 -
OpenGL for Embedded Systems
Per sviluppare l’applicazione tridimensionale è stata utilizzata
un’implementazione, denominata “Gerbera”, delle OpenGL ES,
nuova versione dedicata a dispositivi embedded, creata dalla
Hybrid Graphic Ltd.
Tale implementazione esegue un semplice processo per
determinare automaticamente le capacità del sistema utilizzato
e migliorare le prestazioni. Questo avviene soprattutto testando
se il sistema supporta un qualche tipo di accelerazione
dedicato alle applicazioni multimediali o
Figura 27 – Logo hardware
Hybrid Graphics tridimensionali o se, in caso contrario, il rendering deve essere
effettuato via software e quindi tutti i compiti sono designati alla singola CPU.
Questa versione per sistemi embedded delle OpenGL è una riduzione della
versione 1.5 destinata già ai sistemi desktop. Le specifiche della prima versione
delle OpenGL ES 1.0 fu pubblicata al SIGGRAPH nel 2003, ma oggi esistono
solo poche implementazioni di queste API. La versione ES risulta quindi più
leggera, con codici più brevi, implementazioni hardware separate in istruzioni di
meno di 500K, implementazione con utilizzo di interi e non di valori floatingpoint e con il vantaggio di lavorare su display di piccole dimensioni. Alcune
funzionalità sono state chiaramente eliminate per evitare di appesantire in
modo esagerato le computazioni da effettuare e quindi vengono a mancare ad
esempi i clipping planes definibili dall’utente o alcune operazioni 2D o ancora la
modalità di disegno POLYGON_MODES, alcuni selection/feedback o dei display
list e altri formati di texture monodimensionali o tridimensionali. Per evitare di
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
37
appesantire ulteriormente i calcoli inoltre è stata adottata una matematica fixedpoint e la grandezza dei dati dei vertici è di un byte.
Il framework delle OpenGL ES creato
dalla Hybrid Graphic Ltd funziona su
diversi tipi di CPU e sistemi operativi e
da questa elevata portabilità è nata la
capacità di implementare una versione
dedicata
non
solo
all’industria
videoludica, ma anche ad altri settori,
quali l’industria automobilistica, per
software dedicati quindi alla navigazione
Figura 28 – Framework Gerbera
tramite GPS o per display musicali
futuristici, nell’industria aeronautica, per la creazione di life-critical display, o
addirittura nell’industria militare.
Unica pecca forse di questa implementazione è il fatto che funziona solo su
alcuni devices. Tra i cellulari sono testati e funzionanti solo i modelli Nokia
Series 60: 3650, 3660, 6260, 6600, 6620, 6630, 7610, 7650, N-Gage and N-Gage
QD, per i Pocket PC solo i seguenti: Acer n10/30, ASUS My Pal A620/716, Dell
Axim X-series, hp iPaq h-series, ViewSonic PC V36, Toshiba e-series.
L’implementazione di casa Hybrid Graphic Ltd è inoltre compatibile con i
sistemi desktop Windows 2000 e XP.
4.9 -
Cellulari supportati
Sembra doveroso analizzare i
differenti
cellulari
supportati
dall’implementazione delle OpenGL
ES per capire quali sono le
caratteristiche che li accomunano e il
perché il funzionamento sia ristretto
ad un numero così piccolo di
modelli.
Innanzitutto il sistema sottostante a
tutti i telefoni cellulari presentati è il
SymbianOS e le features dei modelli
stessi sono quelli della Series60.
Non tutti i cellulari della stessa casa
e della stessa serie risultano però
Figura 29 – Cellulari che supportano
funzionanti. Solamente i telefoni
l’implementazione delle OpenGL ES della
Series60 prima edizione sono
Hybrid Graphics Lts
risultati pienamente funzionanti,
ovvero tutti i modelli di tale serie e solo alcuni della seconda edizione della
medesima serie supportano l’implementazione precedentemente descritta delle
OpenGL ES.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
38
La denominazione adoperata da Nokia “series60” indica una serie di
impostazioni che formano una piattaforma comune a diversi produttori, quali
Siemens, LG, Panasonic, Samsung o altri ancora che sfruttano le potenzialità del
sistema operativo SymbianOS, in versione pari o superiore alla 7.0, e che hanno
creato dispositivi con schermi di dimensioni maggiori e una potenza di calcolo
superiore
ai
comuni
telefoni cellulari.
Per capire inoltre il
ridotto
numero
di
telefoni supportati forse
bisognerebbe osservare
attentamente
l’accordo
stipulato tra le due case
finlandesi il 30 novembre
2004, quando solo a
febbraio
la
Hybrid
Graphics
Ltd
aveva
sviluppato
la
prima
implementazione
al
mondo delle OpenGL ES
(dal sito della Hybrid
Graphics).
Figura 30 – Risultati dei test effettuati con l’applicazione
In seguito ad alcuni test
FutureMark SPMark04
svolti nell’ultimo periodo
di lavoro si è inoltre scoperto che non solo i cellulari elencati dalla Hybrid
Graphics risultano funzionanti, ma anche tutti quelli basati su piattaforma
Series60, che posseggono al loro interno una implementazione nativa delle API
utilizzate. Questo permette una portabilità maggiore anche se, a causa della
differente implementazione, alcuni effetti paiono avere comportamenti
lievemente differenti.
Analizziamo, comunque, qui di seguito le caratteristiche di alcuni cellulari,
basati su piattaforma Series60, per dedurre le caratteristiche tecniche comuni,
raccomandando di fare particolare attenzione ai due cellulari adoperati per il
testing: il primo è, come già detto, il Nokia 6600, che sfrutta l’implementazione
delle OpenGL ES della Hybrid Graphic Ltd, e il secondo è il Nokia 6680, con
implementazione nativa, interna al dispositivo stesso.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
39
Figura 31 – Parte delle specifiche tecniche dei cellulari supportati
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
40
Alcuni test sono stati effettuati
da grandi case produttrici di
tools per il benchmark di
sistemi, embedded e non, come
Futuremark Corporation. Una
applicazione
di
testing,
sviluppata proprio con le
OpenGL ES distribuite dalla
Hybrid Graphics Ltd e
destinata quindi ai cellulari
sopra indicati e ad altri che
non hanno alcun tipo di
Figura 32 – Risultati dei test in FPS effettuati con
implementazione
hardware
l’applicazione FutureMark SPMark04
disponibile, è quella che è
stata adoperata per effettuare il confronto tra i differenti telefoni cellulari.
Il confronto ha portato come migliore candidato il cellulare Nokia 6630, avendo
a disposizione una nuova architettura e il doppio dei Mhz, rispetto agli altri
cellulari della serie che supportano l’implementazione scelta.
I test, oltre a confrontare la gestione delle texture da parte dei dispositivi
cellulari, si concentrano su due caratteristiche particolarmente importanti: il fillrate e il 3D polygon troughput.
Il primo consiste nel creare una sorta di texture a
scacchiera e applicargi due texture differenti, le
cui dimensioni sono pari a 128 pixel per lato. Le
due differenti textures vengono poi fatte ruotare
in direzioni opposte e il risultato viene riportato
in milioni di texels per secondo.
L’altro test effettua
invece il rendering
di un torus di 4800
triangoli
senza
alcuna
texture
applicata.
Alla
superfice di questo
oggetto vengono
Figura 33 – Fill-rate test
inoltre calcolate le
dell’applicazione
luci
diffuse,
FutureMark SPMark04
speculari,
di
ambiente e il valore di riflessione. Il risultato, in
questa occasione, viene riportato in centinaia di
triangoli disegnati al secondo.
Figura 34 – 3D polygon troughput
test dell’applicazione
FutureMark SPMark04
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
41
Figure 35 e 36 – Risultati dei test sopra descritti
in textels e in triangoli effettuati con l’applicazione
FutureMark SPMark04
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
42
5 Pokémòn Virtual Pet
5.1 - Descrizione del gioco
Questo gioco differisce in alcuni punti dalla classica visione del Pokèmon come
cucciolo combattente con cui effettuare magiche sfide e sconfiggere
innumerevoli avversari. Questo videogioco è destinato ai più piccoli, visto che,
oramai, i bambini dei nostri tempi sono già in possesso del cellulare intorno ai
nove anni di età.
Lo scopo del gioco è molto semplice: accudire, far crescere ed evolvere il
proprio cucciolo di Pokémòn. L’utente può interagire con il cucciolo in
continuazione, anzi, meno se ne separa e più il cucciolo si sviluppa
velocemente. Qualora l’utente decida di lasciare il cucciolo in stato di
abbandono o non se ne curi per qualche tempo, le caratteristiche che indicano
gli stati fisici ed emotivi del cucciolo caleranno.
5.2 - Pokémòn Virtual Pet – Fase di sviluppo
Lo sviluppo dell’applicazione è iniziato lavorando su alcuni tutorial, esempi e
guide presenti nel World Wide Web e si è concentrato innanzi tutto sull’utilizzo
di librerie per il rendering di modelli tridimensionali. Prima di venire a
conoscenza dell’implementazione delle OpenGL ES resa disponibile dalla casa
Hybrid Graphic Ltd, si è cercato di sviluppare autonomamente un sistema di
visualizzazione di poligoni tridimensionali su un media bidimensionale con
discreto successo, ma l’esistenza dell’implementazione di queste API ha reso
notevolmente più rapido il progresso del progetto, anche se questo ha
significato ripartire nuovamente da zero.
Analizzando alcuni tutorial e iniziando alcune sperimentazioni si è notato
praticamente da subito che la realizzazione di un videogame tridimensionale su
un cellulare di ultima generazione è sicuramente una cosa al passo dei tempi e
non più una visione futurista.
Lo sviluppo si è concentrato principalmente:
- sulla creazione dei modelli, degli opportuni software per convertire i dati
in codice sorgente C++ da utilizzare nell’applicazione stessa,
- sull’utilizzo di alcune funzionalità delle OpenGL ES,
- su come organizzare il main loop del programma,
- su come animare i modelli,
- sulla creazione di un framework che fosse semplice e intuitivo da
utilizzare.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
43
La creazione dei modelli e delle textures ha richiesto all’incirca una settimana di
lavoro per ottenere una prima ottimizzazione che fosse sia somigliante con il
modello originale bidimensionale sia di notevole leggerezza e con un basso
numero di poligoni per evitare di appesantire troppo il calcolo già oneroso della
CPU del cellulare. Per effettuare tale ottimizzazione, oltre alla riduzione
manuale e alle modifiche effettuate con i software CAD precedentemente citati, è
stato usato un particolare tool presente nel pacchetto MilkShape3D,
denominato DirectX Mesh Tools, che permette di adoperare una slidebar per
ridurre automaticamente il numero di facce a quello indicato dal valore
prescelto con la barra di scorrimento. Non è comunque possibile un utilizzo
esclusivo di tale tool in quanto si otterrebbe un modello del tutto deformato e
non più somigliante all’originale.
La creazione delle animazioni del cucciolo di Pokémòn è stata una tra le fasi più
dispendiose del progetto in quanto l’ideazione e la realizzazione dovevano
costantemente essere accompagnate ad una fase di testing non solo
sull’emulatore ma anche sul cellulare in quanto la differenza di calcolo di CPU
non permette di sapere con precisione il risultato finale.
La programmazione in C++, lo sviluppo delle librerie e delle classi necessarie a
risolvere tutte le problematiche del caso hanno rappresentato le parti più
complesse e dispendiose in termini di tempo, questo non solo per la possibilità
limitata di riuso del codice, ma anche per la creazione di un framework
riutilizzabile, per ulteriori sviluppi o diversi videogames.
5.2.1 - I modelli
Lo sviluppo dell’applicazione, subito dopo la fase di analisi per capire se
esistevano possibilità concrete di sviluppare un gioco tridimensionale sul
cellulare e per valutare se la tecnologia moderna permettesse un tale progetto, è
partito con la modellazione tridimensionale del cucciolo virtuale.
a) Poliwag
Figura 37 – Poliwag
In prima istanza si sono sviluppati alcuni tra i Pokémòn più
famosi della serie per stabilire quale potesse essere il
candidato ideale per il videogioco che si intendeva
sviluppare.
Utilizzando Alias Maya 6.5 e
traendo spunto da immagini di
alcuni di questi cuccioli, sono
iniziati i lavori per creare il primo
cucciolo: Poliwag.
Il modello è stato creato in gran parte a partire da una
semplice sfera e le rimanenti parti del corpo da
poligoni di base, come due sfere oblunghe per i piedi,
un torus per la bocca e quattro semisfere per gli occhi
Figura 38 – Modello 3D
di Poliwag
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
44
La semplicità del modello e i pochi poligoni utilizzati potevano essere buoni
punti di partenza per far propendere la scelta in questa direzione. La scarsità
delle possibili animazioni e la poca popolarità del personaggio hanno però fatto
scartare questo cucciolo come personaggio protagonista.
b) Igglybuff
Cercando sempre di trovare dei modelli semplici dal punto
di vista della modellazione e con un numero di poligoni
molto limitato, si è sviluppato il modello di Igglybuff, un
altro personaggio del cartone Pokémòn. Questo modello
offriva un numero maggiore di animazioni in quanto, oltre ai
piedi, è in possesso anche di due piccole braccia. Proprio le
ridotte
di
questi
Figura 39 – Igglybuff dimensioni
apparati, che ricordiamo essere creati
tutti partendo da tronchi di cono mentre il corpo è
chiaramente ancora modellato a partire da una sfera,
hanno fatto sì che si passasse ad un altro genere di
cucciolo, cercando proprio di evitare personaggi con
mani e piedi quasi inesistenti, per poter poi meglio Figura 40 – Modello 3D
di Igglybuff
caratterizzare le animazioni.
c) Bulbasaur
Nel cercare un modello che fosse abbastanza popolare,
facile da modellare e in possesso di arti di media
lunghezza, la scelta è ricaduta su Bulbasaur.
La creazione di questo modello ha richiesto maggiore
elaborazione, anche se in realtà la gran parte dello stesso
è creata da forme solide di base:
due sfere per la testa e il corpo,
quattro cilindri per le zampe e
Figura 41 – Bulbasaur
tre tronchi di cono per ciascun
gruppo di unghie. Le rimanenti parti sono state create
a partire da un’immagine di base che illustrava il
personaggio bidimensionale del cartone, creando
dapprima i contorni delle figure e poi sfruttando la Figura 42 – Modello 3D
di Bulbasaur
potenzialità di Alias Maya e generando quindi in
maniera automatica la superfice racchiusa all’interno.
Questo modello non era privo di difetti, anche se per gran
parte dell’elaborazione successiva, è stato ritenuto un
protagonista valido del gioco stesso: primo tra tutti,
l’elevato numero di poligoni. Sebbene potesse sembrare
abbastanza semplice da modellare, il personaggio, una
volta evoluto, avrebbe dovuto aumentare ancora il suo
numero di poligoni, già elevato, per questioni proprio di
Figura 43 – Ivysaur
immagine e di fattezze dello stesso personaggio: anche
utilizzando alcuni tools di riduzione, come DirectX Mesh
Tool all’interno di MilkShape3D, il modello appariva ancora complesso e
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
45
pesante in termini di computazioni, il che avrebbe portato ad un rallentamento
notevole nel gioco.
c)Pikachu
L’ultimo personaggio ad essere stato modellato è quello che è
poi rimasto il protagonista del gioco stesso: Pikachu.
Con questo modello si è deciso inoltre di procedere in modo
inverso, creare quindi prima il modello evoluto, e poi la sua
“de-evoluzione”. In questo modo si è potuto riscontrare
immediatamente che, una volta
utilizzati i tools di riduzione, il
Figura 44 – Pikachu
modello avrebbe avuto un numero di
poligoni accettabile. La composizione e la fattezza del
personaggio stesso permette inoltre di sfruttare
molteplici animazioni; questo sia per la presenza dei
quattro arti e di una lunga coda, che per le grandi Figura 45 – Modello 3D
dimensioni delle orecchie, che riescono, con il loro
di Pikachu
movimento, a far cambiare l’espressività del personaggio
stesso.
Il modello creato inizialmente, partendo da numerose immagini reperite dal
World Wide Web, per cercare di comprendere al meglio il personaggio e
percepirne una visione completa da più punti di vista, risultava abbastanza
complesso per poter essere importato sul dispositivo di telefonia mobile, tanto
che dopo le opportune modifiche e riduzioni, si è passati dalle 1742 facce
iniziali, contrapposte alle quasi 3000 del primo modello di Bulbasaur, a 404
facce del modello finale adoperato nel videogioco.
Successivamente
è
stato
creato,
modificando il modello della sua
evoluzione, Pichu. Le modifiche effettuate
sono state essenzialmente quelle di scaling
su alcune parti del corpo e di modifica
punto per punto in sezioni delicate del
Figura 47 – Modello 3D
Figura 46 – Pichu modello stesso.
di Pichu
Procedendo di pari passo con la creazione dei modelli si dovevano intanto
creare le varie tessiture da applicare alle superfici degli stessi personaggi. Per
fare questo si è utilizzato un tool presente all’interno di Alias Maya, che
permette di posizionare a piacimento le UV legate ai vertici di un modello,
all’interno di una finestra, e salvare poi il risultato su un file immagine,
solitamente di tipo JPEG, ma le opzioni sono davvero molteplici. Per
posizionare le UV è spesso utile creare degli appositi piani di proiezione per
alcune parti del corpo, oppure adoperare dei tipi di proiezione cilindrici o
sferici per ottenere una disposizione automatica delle UV, di buona qualità.
Una volta ottenuto il file immagine con questo tool, è possibile modificarlo,
come usuale, ed è quindi stato possibile applicare le colorazioni nel modo
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
46
adeguato, così da utilizzare un'unica immagine come texture dell’intero
modello.
Una volta definita questa parte, i modelli sono stati convertiti nel formato 3DS,
acronimo del programma
di grafica vettoriale di casa
Autodesk, 3D Studio Max,
con
l’utilizzo
del
programma di conversione
Deep Exploration, di Right
Hemisphere.
Questo
programma permette di
caricare i modelli in molti
formati, da quelli dei più
famosi tool di disegno e di
grafica vettoriale, a quelli
legati
ad
editor
di
videogames
che
hanno
segnato la storia del
mondo videoludioco. Una
Figura 48 – Alias Maya 6.5 Texture Editor
volta caricato è possibile
visualizzarlo in un frame separato, effettuare delle modifiche di base, senza
poter quindi apportare spostamenti ai vertici, ma potendo ad esempio cambiare
le textures applicate o ribaltare le normali delle facce di un modello. Inoltre
permette anche di visualizzare l’animazione dei modelli e salvare poi tutto in
un altro formato, semplicemente con pochi click del mouse e stabilendo a priori
quali parametri salvare e quali sono le impostazioni da utilizzare.
La conversione si è resa necessaria per poter operare su questi modelli e creare
delle animazioni con MilkShape3D. Si è scelto di sviluppare le animazioni con
questo programma, e non con Alias Maya quindi, per un motivo molto
semplice: il tool utilizzato permette di esportare il lavoro svolto in un formato
ASCII, del tutto chiaro ed autoesplicativo, tanto che è stato possibile, proprio
grazie all’alto grado di leggibilità di questo tipo di file, creare dei semplici
programmi che generassero del codice sorgente in C++ da includere
direttamente nell’applicazione, leggendo semplicemente i dati dal file in
formato MilkShape3D ASCII Format (con estensione TXT).
Si sarebbe potuto operare anche lavorando con le API di Maya per creare un
plug-in da caricare all’interno del programma ed estrarre i dati in file
opportunamente formattati e molto simili a quelli del programma
MilkShape3D, ma il procedimento sarebbe stato molto più lungo e
probabilmente complicato di quello che è stato adoperato, seppur abbastanza
laborioso.
La creazione delle animazioni è un procedimento molto semplice. Il primo
passo, dopo aver importato il modello da utilizzare, consiste nel creare uno
scheletro del personaggio. Semplicemente cliccando sul bottone ‘Joint’ presente
nell’interfaccia del programma, si possono posizionare nello spazio i nodi
corrispondenti al punto di rotazione di ogni osso. Quello che si viene a creare è
un vero e proprio albero di ossa, in cui esiste un nodo radice. Ogni nodo
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
47
dell’albero comanda le rotazioni, sue e di tutti i suoi figli, e lo stesso vale anche
per le traslazioni.
Ad ogni nodo si devono poi
associare i vertici che devono
essere
influenzati
dai
movimenti
di
quel
particolare osso. Per fare
questo basta selezionare i
vertici
che
si
stanno
analizzando e quindi l’osso
interessato e cliccare il
pulsante
‘Assign’
per
memorizzare l’associazione.
Creare
un’animazione
significa
essenzialmente
salvare in specifici keyframes,
Figura 49 – Interfaccia di animazione in MilkShape3D
di una barra temporale che
indica la durata totale dell’animazione, le rotazioni e le traslazioni, e quindi i
dati di movimento, di ogni osso. Una volta salvati tutti questi keyframe,
procedimento molto semplice, eseguito ruotando e traslando le ossa e
schiacciando poi contemporaneamente i tasti ‘CTRL’ e ‘K’, è possibile poi
visualizzare l’animazione, cliccando sul tasto con il simbolo ‘Play’, o salvare il
file ed esportarlo nel formato preferito, che nel caso specifico dell’applicazione
Pokémòn Virtual Pet è quello già descritto, MilkShape3D ASCII Format.
Una volta ottenuto il file con tutti i dati necessari per il rendering e dei vari
keyframes dello scheletro del modello, sono state sviluppate due piccole
applicazioni, sfrtuttando le conoscenze possedute, in linguaggio C, per poter
trasformare direttamente il contenuto del file prodotto da MilkShape3D in altri
tre differenti file contenenti rispettivamente:
- il codice, in linguaggio C++, da inserire all’interno di un file .h
dell’applicazione ‘Pokémòn Virtual Pet’, necessario per il rendering,
- i dati relativi ai vertici, alle normali e alle facce del modello, e quello per
l’animazione diviso in keyframe e loro specifica,
- i dati che legano i vertici alle relativi ossa.
Ottenuto il codice ed inserito nel progetto del videogioco, tramite una serie di
passaggi molto semplici, in realtà limitati a semplici copia e incolla di parti del
file di MilkShape3D, serviva solo creare un’istanza della classe Mesh, di cui si
parlerà meglio in seguito, e inserirgli i dati così ottenuti in pochi e semplici
passaggi.
Per maggiori dettagli relativi all’utilizzo delle due applicazioni, scritte in
linguaggio C, fare riferimento alla Appendice A.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
48
5.2.2 - Primi passi
I primi studi e sviluppi dell’applicazione sono stati in realtà un vero e proprio
periodo di testing. L’applicazione che era stata creata, traendo spunto da alcuni
tutorial disponibili sul World Wide Web, proponeva una grafica poligonale che
non sfruttava alcuna implementazione delle OpenGL ES.
La matematica di base adoperata era in grado di riempire il buffer dello schermo
in maniera tale da rendere l’illusione della terza dimensione. Il buffer, riempito
effettuando una scansione prima orizzontale e poi verticale, veniva riempito
con i dati delle proiezioni dei poligoni su un rettangolo, posizionato in
corrispondenza dello schermo, utilizzando procedimenti abbastanza usuali
della geometria computazionale.
Ai poligoni, suddivisi chiaramente in triangoli
per comodità e semplicità d’uso, si potevano
inoltre applicare delle texture, come di default, e i
colori di queste immagini erano quelli poi
adoperati per riempire il buffer dello schermo.
Tutto il movimento e le animazioni erano
effettuate tramite morphing dei singoli vertici,
anche se questo procedimento, seppur semplice
e lineare, portava via una gran quantità di
Figura 50 – Bulbasaur in movimento memoria e quindi di risorse di sistema.
nella prima applicazione 3D creata
Un procedimento di ottimizzazione minimale,
presente già nell’applicazione di esempio trattata come punto di partenza nello
sviluppo, era quello di creare dei piani di frustum culling, in modo da non dover
effettuare il rendering di tutti quei punti e delle relative superfici che eccedessero
dall’interno del cubo ricreato con questi piani, tra loro chiaramente
perpendicolari.
I modelli e di conseguenza tutto il rendering degli
oggetti e dei personaggi risultava però piatto e quasi
privo di consistenza e di vita, in mancanza
dell’utilizzo di effetti di luci ed ombre, che seppure
fossero stati implementati, non permettevano di
raggiungere un livello di soddisfacibilità accettabile.
Il rendering di caratteri e conseguentemente di scritte
sullo schermo era un’altra operazione sviluppata ma
che non appariva mai adeguata. Il concetto di fondo
era quello di creare una texture contenente una serie
di caratteri ASCII, in modo da creare poi a run-time,
una serie di rettangoli sullo schermo, su cui Figura 51 – Giochi di luci ed
ombre su Pikachu
applicare la sezione di immagine riguardante uno
specifico carattere.
I problemi riscontrati però non erano proprio del tutto irrilevanti. Innanzitutto
il rendering del testo veniva effettuato in maniera corretta solo se i rettangoli,
che in realtà sono suddivisi in due triangoli rettangoli con l’ipotenusa in
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
49
comune, erano posizionati nello spazio tridimensionale a debita distanza dello
schermo, altrimenti alcuni caratteri risultavano illeggibili o addirittura
deformati. La grandezza dei caratteri, tenuto conto del fatto di non poter
cambiarne la distanza dallo schermo e di conseguenza le dimensioni della
proiezione dei rettangoli nel buffer dello schermo, risultava inoltre eccessiva per
le dimensioni limitate dello schermo del telefono cellulare. In ultima analisi,
l’applicazione veniva resa instabile dal rendering del testo. La procedura di
disegno dei caratteri funzionava in maniera corretta, fino a quando,
inspiegabilmente l’applicazione segnalava un errore e si chiudeva. Il debugging
effettuato per trovare eventuali errori o accessi errati alla memoria e le
correzioni apportate al codice e le ulteriori modifiche per prevenire eventuali
accessi a dati non presenti o a sezioni di memoria inconsistenti, non sono state
sufficienti a rendere l’applicazione stabile, né a rivelare quale condizione fosse
la causa del malfunzionamento.
5.2.3 - OpenGL ES
Il riscontro dell’esistenza di API come le OpenGL per telefoni cellulari, in
versione dedicata quindi agli Embedded Systems, ha permesso di riconsiderare il
lavoro precedentemente svolto e iniziare nuovamente da capo, per sfruttare le
potenzialità di queste librerie grafiche e migliorare e velocizzare il lavoro
futuro.
Una volta analizzati alcuni esempi e tutorial presenti in internet, si è capito
subito che il balzo in avanti che si sarebbe portato nell’applicazione sarebbe
risultato davvero sostanziale. Nonostante ciò bisogna notare che alcune
limitazioni sono comunque poste anche in questa implementazione del gioco e
soprattutto nella fase di sviluppo si è dovuto porre attenzione ad argomenti
particolari.
L’impossibilità dell’utilizzo di valori float è forse la limitazione più grande che è
oggi presente nei telefoni cellulari. Il fatto di dover utilizzare solo valori interi è
una enorme barriera al porting tra sistemi fissi e sistemi embedded. Questo non
solo perché bisognerebbe rivedere quasi completamente il codice scritto in
precedenza, ma anche perché la mancanza di valori floating-point porta con sé
numerosi problemi, come l’assenza di valori intermedi tra 0 e 1 e quindi,
pensando ad una animazione, ad una visione a scatti, senza possibilità di
mediare tra due differenti posizioni intermedie.
La mancanza di valori floating-point indica comunque che sarebbe un errore
anche solo provare ad implementarla, in quanto il rallentamento che questi
valori porterebbero nei calcoli tridimensionali sarebbe veramente eccessivo.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
50
Fortunatamente l’esistenza della matematica fixed-point, porta a poter utilizzare
comunque dei valori decimali, che sono di grande importanza nella matematica
tridimensionale. I numeri fixed-point non sono nient’altro che una sequenza di
bit, generalmente 32 bit come gli interi, in cui una sezione di questi rappresenta
la parte decimale del numero. Ad esempio un numero fixed-point scritto in
notazione 24:8 indica che saranno riservati 24 bit per il numero e 8 bit per la
parte decimale. Le OpenGL ES implementano al loro interno questi numeri
fixed-point in notazione 16:16, con 16 bit destinati sia al numero che alla parte
decimale dello stesso, ma altre librerie grafiche o motori grafici destinati a
sistemi embedded devono implementare a parte questa matematica di base in
quanto essa non è presente all’interno della architettura dei processori ARM dei
telefoni cellulari.
Le OpenGL ES non supportano inoltre
tutti i tipi di primitive, come nella
versione destinata ai sistemi non
embedded, ma solo 7 sono le candidate
prescelte: i punti (GL_POINTS), le
linee (GL_LINES), i loop di linee
(GL_LINE_LOOP), lo stripping delle
linee (GL_LINE_STRIP), i triangoli
(GL_TRIANGLES), lo stripping dei
triangoli (GL_TRIANGLE_STRIP) e il
ventaglio
di
triangoli
(GL_TRIANGLE_FAN).
I tipi di dati utilizzati all’interno delle
OpenGL ES sono quelli definiti nel file
‘gl.h’, che contiene le varie definizioni
Figura 52 – Primitive supportate
utilizzate poi nelle applicazioni. Tra i
dalle OpenGL ES
più comuni tipi di dati presenti e
quindi che vengono definiti come tipi all’interno della libreria OpenGL
troviamo i seguenti:
typedef unsigned int GLenum;
typedef unsigned char GLboolean;
typedef unsigned int GLbitfield;
typedef signed char GLbyte;
typedef short GLshort;
typedef int GLint;
typedef int GLsizei;
typedef unsigned char GLubyte;
typedef unsigned short GLushort;
typedef unsigned int GLuint;
typedef float GLfloat;
typedef void GLvoid;
typedef int GLfixed;
L’inizializzazione del sistema di rendering delle OpenGL nei sistemi embedded è
pressoché simile a quanto avviene nei sistemi tradizionali supportati dalle
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
51
OpenGL, come Windows MacOS o Linux, ma alcune differenze sostanziali e
limitazioni appaiono proprio già in questi passi iniziali.
Come prima cosa tre sono le variabili dichiarate solo per il display, il contenuto
del rendering e la finestra in cui disegnare:
#include <GLES/gl.h> // OpenGL ES header file
EGLDisplay iEglDisplay; // display where the graphics are drawn
EGLContext iEglContext; // rendering context
EGLSurface iEglSurface; // window where the graphics are blitted
Successivamente viene chiamata la funzione eglGetDisplay(), passandogli come
parametro il valore, definito nelle API stesse, EGL_DEFAULT_DISPLAY. Una
volta creato il display bisogna inizializzarne il contenuto con la funzione
eglInitialize():
/* Get the display for drawing graphics */
iEglDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY );
/* Initialize display */
eglInitialize( iEglDisplay, NULL, NULL );
La superficie di disegno deve essere creata rispetto a una configurazione
specifica che si vuole adoperare. Per inoltrare al sistema sottostante quali siano
le configurazioni disponibili basta utilizzare la funzione eglGetConfigs(); se
invece si vuole adoperare un parametro paricolare si può utilizzare la funzione
eglChooseConfig(). Questo passaggio è di particolare importanza in quanto è in
questo momento che avviene il legame tra il sistema sottostante, le API e lo
schermo e quindi tutte le sue caratteristiche, come dimensioni, colori o altro
ancora.
EGLConfig config;
EGLConfig *configList = NULL;
int configSize = 0;
int numOfConfigs = 0;
eglGetConfigs( iEglDisplay, configList, configSize, &numOfConfigs );
configSize = numOfConfigs;
configList = (EGLConfig*)User::Alloc( sizeof(EGLConfig)*configSize );
TDisplayMode DMode = Window().DisplayMode();
TInt BufferSize = 0;
switch(DMode)
{
case(EColor4K):
BufferSize = 12;
break;
case(EColor64K):
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
52
BufferSize = 16;
break;
case(EColor16M):
BufferSize = 24;
break;
case(EColor16MU):
BufferSize = 32;
break;
default:
_LIT(KDModeError, "unsupported displaymode");
User::Panic( KDModeError, 0 );
break;
}
const EGLint attrib_list[] = { EGL_BUFFER_SIZE,BufferSize,
EGL_DEPTH_SIZE,16,
EGL_NONE };
eglChooseConfig( iEglDisplay, attrib_list, configList, configSize,
Configs );
config = configList[0]; // Choose the best EGLConfig. EGLConfigs
User::Free( configList ); // free configList, not used anymore
La parte finale dell’inizializzazione è quella che crea
la superficie di disegno e la lega al thread del
rendering dello schermo del sistema embedded. Si crea
in particolare una finestra di rendering e la si pone in
primo piano davanti a tutti gli altri rendering del
sistema embedded (questo porta quindi al fatto di non
poter più utilizzare le API specifiche del telefono
cellulare adoperato in quanto il rendering di queste
ultime viene coperto da quello effettuato dalle
OpenGL ES).
Figura 53 – Schermo
inizializzato
iEglSurface = eglCreateWindowSurface( iEglDisplay, config, &Window(),
NULL );
iEglContext = eglCreateContext( iEglDisplay, config, NULL, NULL );
eglMakeCurrent( iEglDisplay, iEglSurface, iEglSurface, iEglContext );
5.2.4 - Nokia API
Il rendering delle OpenGL ES si lega in modo stretto a quello effettuato dal
sistema embedded. Nel caso specifico del ‘Pokémòn Virtual Pet’ le OpenGL
vengono adoperate per tutta la parte che concerne il gioco, il menù e la parte
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
53
tridimensionale. Le API della Nokia vengono però adoperate in tutti quei casi
in cui è necessario visualizzare del testo sullo schermo. Questo sia per ovviare
alle problematiche già spiegate in precedenza delle texture fonts, sia per ottenere
una qualità grafica migliore e permettere inoltre l’interazione e lo switching tra il
rendering del sistema e delle librerie grafiche.
Nello sviluppare questo scambio di contesto di rendering e quindi nel gestire i
font e le scritte, inizialmente sono state riscontrate parecchie difficoltà; questo
sia per la mancanza di tutorial o articoli ben descritti ed esplicativi, sia per il
fatto di non aver intuito subito che il rendering delle OpenGL ES copre
definitivamente tutto il rendering effettuato dal sistema sottostante, che viene
comunque fatto, seppur non essendo reso visibile.
Le API distribuite all’interno del Nokia SDK permettono di ottenere, in modo
semplice, un riferimento alla finestra corrente di rendering del sistema embedded
e di disegnare, sopra di essa, del testo o delle immagini o quant’altro fosse
necessario (ricordiamo però che le OpenGL ES sovrascrivono questa fase di
rendering). L’utilizzo di differenti font disponibili all’interno del telefono
cellulare è inoltre possibile grazie a semplici chiamate di funzioni, che
consentono, tra l’altro, di ottenere anche il font utilizzato di default dal
dispositivo mobile ed utilizzarlo immediatamente.
CWindowGc& gc = SystemGc();
TRect rect = Rect();
TPoint point(0,0);
const CFont* font = iEikonEnv->NormalFont();
gc.SetBrushColor(KRgbWhite);
gc.Clear(rect);
gc.SetPenColor(KRgbBlack);
gc.UseFont(font);
Stabilire cosa scrivere a schermo è compito del game designer o comunque dello
sviluppatore; le API della Nokia permettono di farlo con un semplice
assegnamento ad una variabile di tipo LIT8.
Per disegnare il testo sullo schermo è solo necessario stabilire il punto da cui
esso deve partire; il testo verrà scritto procedendo alla destra del punto stesso.
Occorre quindi utilizzare la funzione DrawText() relativa alla finestra stessa che
permette di disegnare il testo.
_LIT(KTitle,"Caricamento in corso...");
point.iX = rect.Width()/2 - font->TextWidthInPixels(KTitle)/2;
point.iY = rect.Height()/2;
gc.DrawText(KTitle,point);
L’utilizzo di scritte è stato adoperato per mostrare sia le istruzioni del gioco,
accessibili dal menu in pochi passaggi, sia per la sezione delle statistiche, che
riguardano la situazione psico-fisica del cucciolo virtuale.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
54
La gestione dei files è stata un'altra operazione che ha richiesto parecchie risorse
e lavoro. Per poter effettuare il salvataggio delle statistiche e quindi poter
interrompere una partita e continuarla in un secondo tempo, era necessario
scrivere i valori da qualche parte. Un semplice file di testo è sembrata la
soluzione più banale ed adeguata.
La scrittura sul file dei valori corrispondenti allo stato del cucciolo avviene
quando il programma sta per essere chiuso. Nella procedura di chiusura
dell’applicazione è stato inserito il codice relativo al salvataggio su un file, dei
valori interi sopra indicati.
La lettura dal file invece avviene ogni qual volta il gioco viene aperto.
Chiaramente si è dovuto porre un controllo sull’esistenza del file, o sulla
positività dei valori letti, in quanto non sono ammessi valori negativi nelle
statistiche poichè, se il valore corrispondente alla salute del Pokémòn fosse zero
o ancora meno, il gioco sarebbe resettato.
La scrittura su file avviene creando un riferimento ad uno specifico file che si
vuole trattare: aprendo quella che è definita una vera e propria sessione di
operazioni su file, si accede al file indicandone il percorso specifico, come in un
sistema classico.
TFileName appFullName = CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
TParse parse;
#ifdef __WINS__
parse.Set(_L("c:"), &appFullName, NULL );
#else
parse.Set( appFullName, NULL, NULL );
#endif
TFileName iPath;
iPath = parse.DriveAndPath();
TFileName savegame_name;
savegame_name.Copy( iPath );
savegame_name.Append( _L("save.txt") );
RFs fsSession;
RFile file;
User::LeaveIfError( fsSession.Connect() );
TInt err= file.Open( fsSession, savegame_name, EFileStreamText|EFileWrite|EFileRead|EFileShareAny
);
if( err==KErrNotFound )
err=file.Create( fsSession, savegame_name,
EFileStreamText|EFileWrite|EFileRead|EFileShareAny );
TBuf8<256> data;
Una volta aperta la sessione e ottenuto il riferimento al file, si può scrivere
all’interno qualsiasi cosa, semplicemente utilizzando una sintassi simile a quella
che si adopera solitamente in una chiamata printf() in C.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
55
data.Format( _L8("%d\n"), iAppContainer->iPokemon->pLife );
file.Write(data);
Bisogna sempre ricordarsi di chiudere la sessione precedentemente aperta per
evitare errori vari e operazioni non corrette sul file, con una chiamata alla
funzione Close():
fsSession.Close();
5.2.5 - Input e keypad
Per interagire con il cucciolo virtuale era senza dubbio necessario utilizzare la
pressione di alcuni tasti o comunque far apparire un menu a tendina con i
comandi e permettere quindi l’interazione dell’utente con il cucciolo.
L’ipotesi del menù a discesa è stata scartata in quanto sarebbe risultato alquanto
scomodo e noioso dover eseguire molti passaggi che possono tranquillamente
essere sostituiti da un semplice pulsante. L’esistenza di ben 12 tasti, che
sicuramente sono comuni a tutti i dispositivi cellulari in quanto rappresentati
dai soli numeri e, i due rimanenti, in genere dai caratteri ‘*’ e ‘#’, è parsa
un’opportunità troppo allettante per poterla tralasciare.
L’idea per la gestione dell’input è quella di creare delle semplici variabili
booleane che indicano quando il tasto è in fase di pressione o quando, al
contrario, rimane sollevato. In questo modo il semplice controllo posto su
variabili di stato permette di controllare tutta la gestione dell’input.
La gestione può essere fatta a più livelli e demandata quindi a diversi gestori
dell’input, a livello dell’interfaccia, di sistema e di gioco, per la caratteristica
propria dell’architettura dei dispositivi “Series60”. Nel caso specifico del gioco,
non essendoci la necessità di assegnare alcun compito al sistema sottostante, ad
eccezione del rendering, e dovendo gestire a parte l’interfaccia, la gestione
avviene proprio all’interno del gioco stesso.
Se non implementata in alcun modo, la gestione del keypad, provoca solamente
la retroilluminazione dello schermo, qualora, per questioni di risparmio
energetico imposte dalle case produttrici stesse, il telefono fosse rimasto
inattivo per molto tempo, sebbene le computazioni continuino al suo interno.
Proprio per impedire lo stand-by dell’illuminazione, si è dovuto attuare un
procedimento che inviasse una sveglia al dispositivo, dopo un breve periodo di
tempo, e procedesse a retroilluminare lo schermo stesso.
Una semplice chiamata, ResetInactivityTime(), permette di ovviare a tale
problema, stabilendo dopo quanto tempo bisogna rieseguire tale chiamata con
la funzione After(); questa prende come parametro un valore intero, che indica,
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
56
in millisecondi, il tempo che deve passare tra una chiamata e l’altra, il tutto
all’interno del main loop dell’applicazione stessa:
User::ResetInactivityTime();
User::After(0);
In questo caso la retroilluminazione è continua.
5.2.6 - GUI
La creazione di un menù e di quella che si può definire una GUI (Graphical User
Interface) elementare, è stato un passo inevitabile da accostare alla creazione del
videogioco.
Il menù iniziale, al contrario delle istruzioni e delle statistiche interne al gioco
stesso, è sviluppato sfruttando le OpenGL ES. Questo è stato reso possibile
mediante un semplice espediente adoperato per disegnare il menù. Il trucco
consiste nell’aver creato preventivamente tre immagini differenti: tre, come le
possibili opzioni presenti all’interno del menù, ‘Start’, ’Istruzioni’ ed ‘Esci’, in
cui apparisse selezionata, alternativamente, solo una delle possibili scelte. Il
rendering viene poi effettuato su un semplice rettangolo, su cui viene applicata
la tessitura desiderata, a seconda dell’interazione dell’utente.
Figura 54 – Le tre immagini che costituiscono il menù
Questa soluzione è stata preferita all’utilizzo delle
API del Nokia SDK poichè permette di personalizzare
maggiormente il videogioco e il suo menù iniziale,
inoltre la sua facilità di implementazione ed utilizzo
non
è
paragonabile
a
quella
alternativa,
appositamente scartata.
Le indicazioni, che vengono
fornite costantemente nella
parte dello schermo e che
indicano quindi i tasti per Figura 55 – Immagine con le
indicazioni del gioco
tornare al menù o per
accedere alle statistiche del cucciolo, sono anch’esse
state implementate con l’utilizzo delle OpenGL ES.
La sostanziale differenza tra l’utilizzo di questa texture
e le precedenti è quella che l’immagine relativa alle
Figura 56 – Immagine del indicazioni contiene una sostanziosa parte colorata in
gioco in cui viene effettuato nero, di cui però non viene effettuato il rendering.
il blending
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
57
Questo è possibile grazie ad una tecnica chiamata ‘blending’ delle immagini, che
consiste, come suggerisce la stessa parola inglese, nel fondere la texture,
applicata allo stesso rettangolo adoperato per il menù, con l’immagine che è già
stata renderizzata nel buffer dello schermo e sostituire quindi ogni pixel di colore
nero della texture con il relativo pixel del buffer stesso.
5.2.7 - Audio
Un videogame, come un film o il mondo stesso, senza il feedback audio o suoni e
musiche di sottofondo, perde gran parte del suo fascino. Creare dei suoni,
rumori o un motivo, che facesse da accompagnamento durante tutta la durata
del gioco, è stato un lavoro che ha richiesto qualche tempo e a cui sicuramente
bisogna prestare attenzione.
Trattandosi di un gioco che ha come protagonista principale un cucciolo, la
prima esigenza è stata quella di fargli emettere qualche suono. Il feedback,
ricevuto oltre che dai movimenti anche dai versi del Pokémòn, permette di
rendere ancora più realistico il gioco stesso. D’altra parte ogni cosa che ci
circonda provoca un suono, seppur lieve, e per simulare una realtà è sempre
meglio cercare di riprodurne ogni suo particolare e cercare di non trascurarne i
più importanti.
Per ottenere dei versi che fossero del tutto simili a quelli del cucciolo
protagonista, Pichu (o Pikachu, una volta evoluto) è stato svolto un lavoro di
ricerca nel web e di registrazione direttamente dalla realtà o da filmati del
cartone Pokémon, dei versi dello stesso cucciolo.
Una volta ottenuto un
buon numero di questi file
si è dovuto operare su di
essi. Innanzitutto è stata
effettuata una cernita, in
quanto inserire un numero
troppo elevato di suoni e
file
audio
all’interno
dell’applicazione avrebbe
implicato
l’espandersi
delle
dimensioni
del
videogioco
stesso.
Successivamente
si
è
Figura 57 – Registratore di suoni di Microsoft Windows XP
operato per ridurne le
dimensioni
e
per
modificare alcuni parametri in modo da permettere ai telefoni cellulari di
poterli riprodurre senza difficoltà o alcun effetto di distorsione.
Utilizzando il Registratore di suoni fornito con Microsoft Windows, si sono
potuti modificare i parametri dei file, per raggiungere, sia le impostazioni
adeguate e necessarie per i telefoni cellulari, sia le dimensioni adeguate. La
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
58
modifica più importante è stata effettuata forse sul file che corrisponde alla
musica di sottofondo del gioco stesso. Effettuare un taglio netto in un punto
imprecisato della canzone originale, avrebbe provocato un effetto alquanto
sgradevole, nella ripetizione continua, in loop, che viene eseguita
nell’applicazione. Il motivo dura infatti solamente 18 secondi e viene poi
ripetuto in continuazione all’interno dell’applicazione, effettuando una
riproduzione in looping.
Per permettere la riproduzione dei file, in modo univoco, in base a determinate
reazioni del cucciolo, e della musica di sottofondo, in modo ripetuto, sono state
create differenti classi, di cui una in particolare, la classe CSndMixer, che si
occupa di gestire tutti i suoni, il volume, controllare la riproduzione, continua o
singola, e di settare i parametri dei file WAV stessi.
5.2.8 - Framework
Analizziamo qui di seguito il framework generato, le classi create e gli algoritmi
per risolvere tutte le complessità del caso, ad eccezione delle classi che
gestiscono strutture matematiche e le loro operazioni, approfondite nella
Appendice B.
3DObjects.h
Questo file contiene effettivamente tutti i dati
necessari per effettuare il caricamento e quindi il
successivo rendering degli oggetti tridimensionali. I
dati presenti in questa libreria sono essenzialmente
l’output dei due programmi, scritti in C, che generano
strutture dati ad hoc per l’applicazione stessa, descritti
con cura all’interno dell’Appendice A.
CMixerThread.h
e
CMixerThread.cpp
All’interno di questi file compare la classe
‘CMixerThread’ che rappresenta il thread che si
occupa della gestione dell’audio.
CSndMixer.h
e
CSndMixer.cpp
La classe ‘CSndMixer’ ha il ruolo di fare da
coordinatore di tutti gli effetti audio dell’applicazione
stessa: può settare il volume, scegliere quale file
riprodurre, in che modalità, e che canale audio fargli
utilizzare, per un massimo di otto canali.
CWavLoader.h
e
CWavLoader.cpp
La classe che si occupa di caricare direttamente dal
disco i file .wav utilizzati per riprodurre i suoni e i
versi del cucciolo è appunto la classe ‘CWavLoader’.
Mesh.h
e
Mesh.cpp
Questi file contengono la classe ‘Mesh’ che gestisce i
modelli tridimensionali, le loro texture e la fase di
rendering, e che sfrutta le OpenGL ES.
Utilizzando differenti metodi viene effettuato il
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
59
caricamento di tutti i dati necessari per inizializzare la
mesh, sia essa statica o dinamica, gestirne quindi il
posizionamento, le dimensioni e la rotazione.
L’animazione scheletrica e il suo funzionamento sono
un elemento chiave di questa classe e permettono con
due semplici metodi di far muovere in modo semplice
ed efficace un qualsiasi modello.
Pokemon.h
e
Pokemon.cpp
In questi file è presente l’intero codice della classe
‘Pokemon’ che rappresenta la gestione del gioco vera e
propria e quindi i suoi metodi, gli algoritmi di
gestione della crescita del cucciolo, dell’interazione tra
i differenti modelli e dell’avanzamento delle
animazioni relative alle diverse pressioni dei tasti del
cellulare.
In questa classe è presente il main loop dell’intero
gioco che si scinde in tre grandi parti, la
presentazione, il gioco e il menù.
Pokemonapp.h
e
Pokemonapp.cpp
La classe ‘Pokemonapp’ è la classe che crea l’oggetto
applicazione che viene poi gestito dal sistema
Symbian OS.
Pokemonappui.h
e
Pokemonappui.cpp
In questi file avviene tutta la gestione dell’interfaccia,
a partire dal caricamento delle texture, dalle scritte e
l’utilizzo dei fonts di sistema, fino ad arrivare allo
swapping del buffer e al refresh dello schermo stesso.
Nella classe ‘Pokemonappui’ viene effettuata inoltre
l’inizializzazione della classe ‘Pokemon’ sopra
descritta e gestito quindi il suo avvio o il salvataggio
automatico in uscita.
Pokemoncontainer.h
e
Pokemoncontainer.cpp
In questi file avviene l’inizializzazione delle OpenGL
ES e in pochi semplici passi vengono richiamati alcuni
metodi delle classi precedentemente descritte,
riguardanti le varie inizializzazioni; vengono quindi
caricati anche i file musicali e i suoni ed infine viene
fatto partire ed avanzare il timer dell’applicazione con
il passaggio dal gioco alla schermata delle statistiche.
Utils.h
e
Utils.cpp
Questi file contengono una serie di utilities, create e
distribuite dalla casa finlandese Nokia, per permettere
la gestione di alcune operazioni in modo più facile ed
intuitivo sui suoi modelli di cellulari e sull’emulatore
distribuito direttamente all’interno dell’SDK.
Per un analisi del codice completo di tutte le parti mancanti, riferirsi alla
Appendice C.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
60
5.2.9 - Pacchetti SIS
Terminato il lavoro di sviluppo e di compilazione, considerando che
l’emulatore, come già detto, non restituisce una prova certa del corretto
funzionamento di un’applicazione, né della velocità di esecuzione o
caricamento dei dati, poichè sfrutta le potenzialità del processore del computer
su cui viene fatto eseguire, era necessario testare il videogioco direttamente su
un telefono cellulare.
L’utilizzo del Nokia SDK ha reso possibile creare un unico pacchetto,
contenente anche una procedura di installazione dell’applicazione, da mandare
poi via etere, bluetooth, infrarossi o altri metodi, al dispositivo cellulare stesso.
Per adoperare tale procedimento è necessario creare un file di testo contenente il
percorso specifico di tutti i file adoperati dall’applicazione e il percorso di
destinazione sul telefono cellulare, in modo da evitare di creare inconsistenze di
dati o ricerca in directory errate.
Una volta eseguito questo importante passaggio, è necessario compilare l’intero
codice dell’applicazione in modalità atta a preparare l’applicazione e
l’eseguibile, prodotto dalla compilazione stessa, per essere elaborato da
processori ARM, con una semplice chiamata da Prompt dei comandi: “abld build
armi urel”, che indica anche di compilare il codice in modalità Release.
Creato quindi l’eseguibile con il metodo appena descritto,
con estensione APP, ed il relativo pacchetto, con estensione
PKG, con l’esecuzione della chiamata ‘makesis’, da Prompt
dei comandi, è possibile creare il file, con estensione SIS, da
caricare direttamente sul telefono cellulare.
Una volta aperto il file appena trasferito sul dispositivo,
viene avviata una procedura di installazione che permette
di creare direttamente sul cellulare le directory richieste e di
Figura 58 – Vista
copiarvi all’interno i file necessari, per poter poi eseguire
All’interno del
l’applicazione, semplicemente cliccando sull’icona relativa
menù dell’emulatore
all’interno del menù del telefonino.
Series60
5.3 - Pokémòn Virtual Pet – Caratteristiche tecniche
Questa applicazione è stata testata sia sull’emulatore fornito con il Nokia SDK,
sia sui cellulari Nokia 6600 e 6680. La sostanziale differenza riscontrata nel
portare il gioco su sistema embedded è quella della velocità di esecuzione delle
istruzioni e quindi della rapidità del refresh e del rendering, soprattutto per
quanto riguarda il primo modello: per ottenere un livello di giocabilità
accettabile, anche su questo cellulare, l’avanzamento temporale di tutti i
movimenti e delle animazioni è stato quadruplicato.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
61
Bisogna tenere in considerazione che l’applicazione testata non ha subito il
naturale processo di ottimizzazione richiesto solitamente ai videogames e che
l’ingente numero di poligoni animati, di cui viene effettuato il rendering,
influisce, per la gran parte, sul risultato finale.
Con il framework creato e grazie all’utilizzo delle OpenGL ES ed
all’implementazione di queste API, della Hybrid Graphics Ltd, si riesce a
mantenere un buon livello di giocabilità effettuando il rendering di circa 10001500 poligoni, ricordando che si parla di prestazioni ottenute senza alcuna
ottimizzazione e della presenza di suoni, luci, ombreggiature e texturing.
Riassumiamo inoltre, qui di seguito, le specifiche tecniche del cellulare
principalmente utilizzato per il test, il primo tra i due, in quanto risulta assai
importante notare che questo particolare modello è in realtà quello che ha le
performance peggiori sia a causa della velocità del processore, sia per l’assenza di
hardware dedicato alle applicazioni multimediali o tridimensionali.
Per ulteriori confronti sui modelli abilitati all’utilizzo delle OpenGL ES o ai
relativi benchmark tridimensionali, riferirsi al capitolo 4 ( Cellulari supportati ).
Specifiche tecniche Nokia 6600
• Sistema Operativo Symbian 7.0s
• Conforme alle specifiche di piattaforma Series 60, 2nd edition
• Processore ARM9, clock 104MHz
• Java: CLDC 1.0, MIDP 2.0, Wireless Messaging API (JSR-120), Mobile Media
API
(JSR-135), Bluetooth API (JSR-82 No OBEX), Nokia UI API
• Display 176x208 pixel, 65k colori
• Polifonia a 24 canali, True Tones (WB-AMR)
• Memoria: 3MB heap, 6MB condivisa per la
memorizzazione
• Supporto per memory card MMC
• Dimensione illimitata dei file .jar
• Connettività Bluetooth e infrarossi
• GSM 900MHz / GSM 1800MHz / GSM
1900MHz
• GPRS Class 6 (3+1/2+2 slots)
• WAP 2.0, XHTML over TCP/IP
• Fotocamera VGA integrata
Figura 59 – Nokia 6600
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
62
5.4 - Pokémòn Virtual Pet – Il gioco
Pokémòn
Virtual
Pet
è
un’implementazione
tridimensionale del famoso Tamagotchi.
Lo scopo del gioco è, come già detto, accudire, far crescere
ed evolvere il proprio cucciolo di Pokémòn facendo
interagire l’utente con il suo cucciolo, che cambia stati fisici
ed emotivi di conseguenza.
Diversi sono i tipi di interazione con il cucciolo virtuale e a
ciascuno di essi è stato designato un pulsante differente Figura 60 – Splash
screen del gioco
della tastiera del telefono cellulare, in modo da rendere
molto rapido l’apprendimento da parte dell’utente dei
semplici comandi di gioco.
Analizziamo qui di seguito le varie opportunità di gioco, di interazione e le
varie fasi di sviluppo del Pokémòn e come questo reagisce in presenza o meno
del suo “padroncino”.
Facendo partire l’applicazione, dopo alcune schermate di
caricamento, comparirà il menù, all’interno del quale si
possono facilmente compiere tre azioni, con il solo utilizzo
delle frecce direzionali o del joystick, se presenti sul
cellulare: iniziare il gioco, leggere le istruzioni oppure
abbandonare e chiudere l’applicazione. Durante il gioco, in
qualsiasi momento, basterà premere il tasto numero - 0 per accedere a tale menù.
All’inizio del gioco, se è la prima volta
che si utilizza l’applicazione, il cucciolo
di Pokémòn si trova all’interno della sfera Pokè. Dopo
qualche attimo di attesa, la sfera si schiude, il cucciolo
scavalca la parte inferiore della sfera e si avvicina
direttamente all’utente fino a raggiungere la parte centrale
dello schermo, dopo di che si mette in attesa che l’utente
interagisca con lui.
Se l’utente non presta attenzione al Figura 62 – Nascita
del cucciolo
cucciolo, questo chiamerà il padrone
per catturare la sua attenzione, oppure approfitterà del
momento di solitudine per sonnecchiare in pace o per
espletare in un angolo i suoi bisogni.
Alla carenza di attenzioni corrisponde però un
peggioramento dello stato fisico e morale del cucciolo
stesso. Bisogna notare difatti che ogni stato psico-fisico del
Figura 63 – Cucciolo Pokémòn è rappresentato da un valore compreso tra 0 e 100.
in attesa
Se tali valori raggiungono contemporaneamente il 100%
allora il Pokémòn si evolverà al suo stadio successivo e quindi nel caso specifico
Pichu si tramuterà in Pikachu. Qualora invece la caratteristica della salute
dovesse raggiungere il valore 0 allora il cucciolo morirà e si dovrà ricominciare
Figura 61 – Menù
del gioco
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
63
la partita dall’inizio. I valori cominciano a
calare quando il cucciolo non si sente più al
centro dell’attenzione del suo padroncino.
L’interazione dell’utente si riflette in
cinque semplici azioni: far mangiare il
proprio
cucciolo,
divertirsi
insieme
giocando, farlo addormentare, curarlo e
pulirlo.
Figura 64 – Evoluzione in Pikachu
Per far mangiare il
proprio cucciolo basta premere il tasto - 1 - e una ciotola
apparirà alla sinistra del Pokémòn per far sì che questo
consumi in tranquillità il suo pasto. Si
vedrà quindi il cucciolo dirigersi verso la
ciotola, chinarsi a mangiare e quindi
tornare al suo posto in attesa di altro da
fare. Dare da mangiare troppo spesso al Figura 65 – Morte
del cucciolo
cucciolo però lo farà stare male e quindi
non bisogna eccedere nel fargli compiere tale azione.
Con il tasto numero - 2 - invece l’utente potrà giocare con il
cucciolo. Questo corrisponde al fatto che il Pokémòn si gira
verso la sua destra e attende che l’utente gli lanci una pallina
in modo che lui possa tirarla indietro colpendola con la
coda. Il lancio della pallina, che avviene sempre alla
pressione del tasto numero - 2 -, deve
essere compiuto tre volte prima che il
cucciolo si ritenga soddisfatto di aver
giocato, in caso contrario questo resterà
Figura 66 – Pichu
che mangia
sempre in attesa di giocare.
Figura 67 – Pichu si
sente male
Il tasto numero - 3 - permette al cucciolo
di accomodarsi su un fianco e passare un
momento di tranquillità e di addormentarsi. Nel corso della
Figura 68 – Un
dormita del cucciolo l’utente può decidere di voler fare
baseball un po’
particolare
qualcosa altro insieme al Pokémòn e
quindi
gli
basterà
schiacciare
nuovamente il tasto - 3 - per svegliarlo e far sì che il cucciolo
si riposizioni in attesa che l’utente decida cosa fare.
Utilizzare il tasto numero - 4 corrisponde alla cura del cucciolo. Una
morsa compare dall’alto per prendere il
Pokémòn dalla coda e innalzarlo fino
Figura 69 – Pichu
alla parte superiore dello schermo dove
addormentato
esso verrà rilasciato per cadere a terra e
rimanere senza coscienza per qualche attimo, fino a che
un’enorme siringa compare per iniettare il liquido curativo
Figura 70 – Il
al cucciolo.
cucciolo necessita
Per pulire il proprio cucciolo bisogna invece utilizzare il
di cure
tasto numero - 6 - che farà comparire una violenta ondata
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
64
d’acqua che lava il Pokémòn e l’ambiente circostante, qualora il cucciolo avesse
espletato i suo bisogni.
Il tasto numero - 5 - permette all’utente di
prendere visione delle statistiche del
proprio cucciolo e quindi di venire a
conoscenza degli attuali valori delle
rispettive caratteristiche di salute, sazietà,
riposo e felicità del Pokémòn.
Oltre a queste preziose informazioni, che
permettono quindi di sapere quanto Figura 71 – Pichu
Figura 72 – Il
viene curato
cucciolo viene lavato manca affinché il cucciolo possa evolversi
o quanto sia vicino il momento del suo decesso, il giocatore
ha anche informazione dello stato attuale del suono.
Una caratteristica infatti innovativa rispetto al Tamagotchi tradizionale è
sicuramente, come già enunciato, la presenza di suoni differenti dai semplici bip
del gioco originale. I suoni
sono differenti a seconda di
cosa vuole comunicare il
cucciolo. Il Pokémòn è, infatti,
in grado di richiamare
l’attenzione dell’utente con un
verso particolare e di
esprimere la sua felicità o il
suo
sforzo
con
versi
differenti.
In
sottofondo
inoltre si può notare la
presenza di una musica che
accompagna costantemente
il gioco, in modo da rendere
l’applicazione più piacevole.
Per attivare o disattivare i
Figura
73
–
La
suoni basterà premere il
tasto numero - 9 - e, come
schermata
delle
detto
in
precedenza,
controllarne lo stato attuale
statistiche
nella
sezione
delle
statistiche.
5.5 - Pokémòn Virtual Pet – L’evoluzione
L’applicazione creata potrebbe chiaramente subire modifiche, miglioramenti e
notevoli sviluppi. Un processo di ottimizzazione del rendering e della gestione
delle variabili interne e del flusso di controllo rappresenterebbero un primo
passo in avanti per una nuova versione del gioco; intendendo con questo non
solo una realizzazione più curata dei personaggi e del texturing, ma proprio una
revisione del codice del programma in termini di riduzioni del numero di
computazioni del processore.
L’essenza stessa del gioco trarrebbe inoltre vantaggio nella presenza della
possibilità di effettuare delle partite in multiplayer, con altri utenti e i loro
cuccioli, in modo da avvicinarsi ancora di più a quella che sarebbe il vero
compito di un Pokémòn e quindi combattere ed evolversi. Questa opportunità,
grazie alle moderne tecnologie Bluetooth, non è oramai più un sogno, anche se
riuscire a testare tale tecnologia sugli emulatori distribuiti, come quello
dell’SDK della Nokia, risulta ancora complesso, poco intuitivo e soprattutto mal
funzionante.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
65
La creazione quindi di nuovi modelli tridimensionali e di opportune
animazioni di combattimento nonchè di altre possibilità di interazioni con il
singolo utente sarebbe una aggiunta inevitabile per ottenere un prodotto
competitivo e sicuramente più completo, permettendo così di poter pensare
proprio a stravolgere ancora di più il gioco e riuscire a trovare ancora meglio
quel filo conduttore che ora separa molto il gioco dalla serie televisiva.
Inoltre un ulteriore miglioramento del framework creato potrebbe essere la
gestione di effetti particolari, particles o altro, per rendere la qualità visiva e
l’immagine del prodotto di livello più elevato, anche se forse per sfruttare le
piene potenzialità delle OpenGL ES e quindi avere un salto di qualità nella
grafica tridimensionale, utilizzando particolari shaders e altre caratteristiche di
una pipeline 3D programmabile, bisognerà aspettare la release della versione 2.0
di queste API, attesa per la seconda metà del 2006, almeno per quanto riguarda
la Hybrid Graphics Ltd.
Una caratteristica importante che un gioco del genere potrebbe avere è quella di
poter pensare di creare una sorta di “Clinica dei Pokémòn”, raggiungibile via
web, che permetta di tenere aggiornato il programma, caricando nuove
evoluzioni, nuovi cuccioli, permettendo di fare degli acquisti per il proprio
Pokémòn e quindi per farlo poi divertire in compagnia. D’altra parte aggiornare
il programma sarebbe una cosa semplice e banale sia per la costituzione del
framework, sia perché, grazie alla gestione dei file creata ed utilizzata, si possono
salvare tutti i dati e l’unica necessità è quella di non sovrascriverli.
Ora che i telefoni cellulari stanno oramai evolvendo, a tal punto che i dispositivi
del futuro avranno dei chip dedicati esclusivamente addirittura ai calcoli
tridimensionali, il Pokémòn Virtual Pet potrebbe evolvere ulteriormente
aggiungendo anche un interfaccia tridimensionale, suoni tridimensionali in
dolby sorround, e, magari, filmati di presentazione iniziali, invece di semplici
immagini.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
66
6 Conclusione
Abbiamo analizzato fin qui tutto ciò che concerne il mondo del mobile gaming,
iniziando da uno sguardo alla storia del mondo videoludico e del telefono
cellulare per analizzare e scoprire il loro punto di incontro, che oggi rende il
telefonino un très d’union tra i due differenti mondi.
Successivamente, ci siamo soffermati ad analizzare le piattaforme esistenti e ne
abbiamo fatto una analisi comparativa che ci ha portato a vedere come il
progresso nel campo dei videogames porti alla corsa al successo delle console
portatili, quindi alla costruzione sempre più rapida e frenetica di nuovi e
sempre più piccoli chip dalle molteplici funzionalità.
L’analisi si è soffermata sul telefono cellulare come dispositivo mobile dedicato
al gioco e come piattaforma mobile per la creazione di community virtuali sempre
in movimento.
Uno studio è stato poi dedicato al dispositivo Tamagotchi, che nonostante le sue
caratteristiche di basso livello, ha garantito uno strepitoso successo mondiale al
cucciolo virtuale. Sono state quindi analizzate le sue caratteristiche tecniche, le
sue qualità e ciò che lo ha contraddistinto da tutti i dispositivi mobile precedenti:
il gioco stesso.
La creazione di una nuova applicazione tridimensionale dedicata a dispositivi
cellulari che traesse spunto dallo stesso Tamagotchi racchiude in sé la chiave
dell’ulteriore analisi svolta.
Sono stati quindi descritti i tools di sviluppo dell’applicazione e come il loro
completarsi a vicenda abbia permesso la creazione dei modelli tridimensionali,
delle loro textures e dei loro movimenti. Una parte è stata dedicata alla
descrizione del gioco e delle differenze rispetto al dispositivo originale di casa
Bandai e alla analisi delle caratteristiche tecniche dell’applicazione ed un’ultima
sezione alla descrizione di una partita di un giocatore ideale.
Sono stati inoltre descritti i telefoni cellulari che supportano l’implementazione
delle OpenGL ES adoperata nello sviluppo dell’applicazione.
Vediamo qui di seguito cosa contraddistingue questa applicazione rispetto alle
precedenti, quali sono le innovazioni apportate e perché risulta importante
adesso, più che mai, concentrare l’attenzione su questo tipo di sviluppo.
6.1 - Analisi e confronto
Pokémòn Virtual Pet presenta una visione nuova e rivisitata sia del Tamagotchi
sia dei Pokémòn stessi.
La maggiore differenza con il dispositivo originale è il grande salto di qualità
che l’applicazione in sé presenta. L’introduzione della terza dimensione e di un
suono stereo, ben differenti dall’immagine piatta e stilizzata e dal bip hardware
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
67
originali, permettono di catturare maggiormente l’attenzione e di trarre tutti i
vantaggi che queste nuove qualità permettono.
Con l’introduzione della tridimensionalità e quindi della profondità, si ha a che
fare con un mondo del tutto differente. I movimenti del cucciolo non sono più
legati: non è quindi più costretto a saltellare in continuazione e con frenesia a
destra e sinistra spostandosi con movimento sinusoidale, ma si può muovere
anche in avanti e indietro o stare anche fermo sul posto e semplicemente girare
su sé stesso, permettendo quindi di avere una piena visione del cucciolo.
L’interazione con altri oggetti guadagna molto dalla terza dimensione: basti
pensare ai momenti di divertimento con il cucciolo nell’applicazione stessa,
quando la pallina viene lanciata al cucciolo e questo la rimanda indietro con la
coda, aumentando quindi la sua felicità.
Sempre a riguardo della grafica, un elemento introduttivo di straordinaria
importanza è sicuramente l’introduzione dei colori. Con l’aggiunta delle
sfumature e delle luci, l’ambiente e il cucciolo perdono l’effetto di “piattezza”
che senza dubbio non contribuiscono a ricreare quella verosimiglianza con la
realtà che oramai è sempre più richiesto, nei giochi moderni, sia dedicati alle
console portatili che da tavolo o, ancora maggiormente, ai computer tradizionali.
Insieme ai colori, la possibilità di effettuare il texturing dei modelli permette
inoltre di ottenere una qualità visiva ancora più alta, senza la costrizione di
avere parti differenti di un modello colorate in modo diverso o un'unica mesh,
colorata in modo uniforme.
L’introduzione del suono stereofonico a 8 canali permette inoltre di avere una
musica di sottofondo, in modo da evitare al giocatore di annoiarsi, costretto ad
osservare un religioso silenzio, e di utilizzare altri supporti multimediali, atti a
riprodurre musica. Inoltre è ancora maggiore l’interattività con il cucciolo e il
senso di verosimiglianza con la realtà.
Osservando il mondo che ci circonda qualsiasi cosa noi facciamo, o qualcun
altro compie, emette un rumore o un suono, seppur lieve. Riproducendo i versi
del cucciolo si permette di avere sia un feedback alle azioni del giocatore, oltre
che visivo, sia un richiamo maggiore dell’attenzione dell’utente.
Tra le due differenti versioni, Tamagotchi e Pokémòn Virtual Pet, viene
mantenuta comunque l’idea di poter visualizzare le caratteristiche del proprio
cucciolo a discrezione dell’utente e quindi sapere cosa sta andando bene o male
nella crescita del proprio Pokémòn.
La maggiore differenza con questi ultimi, invece, consiste proprio nell’avere
una visione pacifica del cucciolo. Il Pokémòn non è quindi più visto come
animale combattente che viene utilizzato per sconfiggere innumerevoli
avversari con colpi segreti e mosse speciali, ma come tenero compagno di giochi
da accudire e coccolare per permettergli di evolversi in modo tranquillo e senza
dover subire ferite o lesioni di alcun tipo.
Viene mantenuta comunque l’idea dell’uscita del Pokémòn dall’interno della
sfera Pokè, per non discostarsi troppo dalla versione originale, anche se questa
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
68
non avviene in seguito ad un violento flash e ad un urlo del tipo “Pikachu,
scelgo te!”, ma semplicemente si vede il cucciolo uscire scavalcando il bordo
della sfera e raggiungere il centro dello schermo per iniziare ad interagire con
l’utente.
Anche la cura del cucciolo dista sicuramente dalla poco significativa visione
originale. Il Pokémòn non viene mandato in una clinica specializzata o
rinchiuso in nessun particolare macchinario o all’interno di alcuna sfera, ma
viene semplicemente medicato per mezzo di una innocua puntura, dopo essere
stato tramortito ed essere quindi del tutto inconsapevole del fatto stesso.
L’originalità del momento di gioco con il cucciolo ed il suo modo di mangiare,
sono altri elementi che probabilmente si discostano dal pensiero della reale
versione dei Pokémòn, ma ai fini della interattività e dell’allevamento stesso del
cucciolo, completano appieno i movimenti del Pokémòn.
La semplicità di utilizzo e le istruzioni integrate all’interno dell’applicazione
stessa rendono il gioco alla portata di tutti e inoltre la possibilità di passare
facilmente dal gioco all’utilizzo classico del telefono cellulare sono un elemento
che promettono sicuramente un interesse in questa direzione. Il dispositivo di
casa Bandai difatti rimane sempre attivo e, perennemente, il cucciolo ha
esigenze particolari, che se non assecondate in modo corretto, portano alla sua
morte. Nella versione tridimensionale sviluppata, invece, la possibilità di
sospendere il gioco in qualsiasi momento e riprenderlo in seguito, in modo
automatico e senza alcun processo particolare, o quella di poter cambiare
applicazione grazie anche al multi-threading dello stesso sistema operativo
sottostante, rendono più fattibile il gioco e non instaurano nel giocatore l’ansia
tipica dei possessori del Tamagotchi.
6.2 - Sintesi finale
Il mondo dell’industria videoludica e il settore mobile si sono incontrati da
molti anni ormai, ma solo dalla fine del 2004 si sono iniziati a vedere le prime
console con giochi tridimensionali o ancora meglio giochi in 3D per i cellulari,
palmari o altro genere di dispositivi portatili.
Nei sei mesi trascorsi, dall’inizio del periodo di tesi ad oggi, il mondo del mobile
gaming ha subito una rivoluzione tale da segnare definitivamente un
cambiamento nel corso della storia del mobile.
Se sei mesi fa il concetto di gioco per telefono cellulare era limitato all’uso di
una grafica a colori piatta e bidimensionale, oggi si può finalmente parlare di
terza dimensione.
In precedenza si è accennato anche alla nuova console di casa Nintendo, il DS, e
al gioco in stile “cucciolo virtuale” ad esso dedicato, NintenDogs. Quando si è
iniziato a pensare al modo di testare la possibilità di usufruire della grafica
tridimensionale su dispositivi di telefonia mobile, non si era a conoscenza di
questo gioco e delle sue potenzialità.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
69
Il cambiamento subito nel mondo dei telefoni cellulare è evidente anche perché
sei mesi era improbabile trovare sul mercato degli smartphone con un costo
inferiore ai 100 euro. Oggi, la grande varietà di dispositivi disponibili, i continui
sviluppi e la perpetua corsa alle funzionalità aggiunte e ai chip dedicati, hanno
fatto calare i prezzi.
Le stesse case produttrici di videogames sono state costrette ad aggiornarsi e a
tenersi al passo con i tempi. I primi giochi con l’illusione della terza dimensione
erano stati elaborati già in precedenza grazie all’uso della proiezione isometrica,
ma in questi sei mesi sono apparsi sul mercato mondiale i primi videogiochi
tridimensionali e i porting di alcuni tra i giochi più famosi dedicati
precedentemente ai PC o alle console da tavolo. Esempi lampanti di porting
appaiono su molti siti web dedicati ai dispositivi di telefonia mobile e sono
quelli degli sparatutto Doom e Quake III o, solo ultimamente, del gioco di
strategia Age of Empires.
I videogiochi sopra citati e gli altri di cui viene effettuato il porting non sempre
riescono ad avere sul cellulare gli stessi risultati precedentemente ottenuti sul
computer o sulle altre console, questo sia per le dimensioni dello schermo o per
la mancanza di effetti adeguati, sia per la difficoltà dell’utilizzo della tastiera
numerica del telefonino rispetto a quello di un mouse o di un pad dedicato.
Questo non impedisce comunque il fatto di dover oramai considerare il telefono
cellulare adeguato ad essere, sotto forma di smartphone, competitivo con le altre
console portatile disponibili sul mercato mondiale; ciò è sicuramente credibile in
quanto, come già si è detto in precedenza, i cellulari del prossimo anno avranno
capacità di calcolo superiori a quelle delle console dal tavolo di qualche anno fa,
vedi ad esempio il milione di poligoni al secondo annunciati da LG, in
confronto alla Sony Playstation.
Figura 74 - Porting videogames da PC a mobile
In futuro tutti potranno divertirsi, nell’attesa di un autobus o solo per
trascorrere del tempo a rilassarsi, con i propri telefoni cellulari, adoperando
ogni sorta di applicazioni che sfruttino le potenzialità offerte da interfacce
tridimensionali o giochi tridimensionali.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
70
Si è dimostrato che, già con le capacità attuali dei telefoni cellulari di ultima
generazione, è oggi possibile effettuare rendering di scene tridimensionali
abbastanza complesse e si è parlato inoltre dei progetti futuri, ad esempio quelli
della Texas Instruments, di chip dedicati al calcolo tridimensionale o ad altri tipi
di calcoli per supportare le nuove funzionalità dei cellulari.
Capire e sfruttare le potenzialità di queste nuove tecnologie dedicate ai sistemi
embedded è in pratica il futuro di molti settori, non si tratta quindi solo di un
vantaggio fruibile soltanto dall’industria dei videogames.
Con lo studio e lo sviluppo di ulteriori implementazioni di API dedicate
espressamente alla grafica tridimensionale, al suono in dolby surround o di
ulteriori librerie di supporto alla programmazione e alla progettazione, si potrà
pensare ad utilizzare il telefono cellulare non solo come elemento sostitutivo di
un palmare, cosa che già ai giorni nostri sta accadendo, ma anche come lettore
di film o come console portatile, portata ad un livello competitivo alle altre
presenti sul mercato, oppure aggiungendo ancora chissà quante altre
funzionalità.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
71
7.1 Appendice A
In questa appendice viene presentato, semplicemente riportando un articolo,
l’utilizzo della classe Mesh e delle due applicazioni create per mediare in modo
semplice e veloce tra il programma di modellazione tridimensionale, utilizzato
per le animazioni, e l’applicazione creata.
Modelli MilkShape3D e OpenGL ES
In questo articolo spiegherò come usare i modellio di MilkShape3D nelle
applicazioni per sistemi embedded che fanno uso delle OpenGL ES, tra essi ad
esempio cellulari o palmari.
Questo tutorial è basato sull’ormai famoso codice reperibile a questo sito:
http://rsn.gamedev.net/tutorials/ms3danim.asp
Inizierò analizzando la semplicissima classe che conterrà poi tutti i dati della
mesh stessa.
class Mesh : public CBase
{
public:
//Class Constructor
Mesh()
{
delete iVertex;
delete iFace;
delete[] iGLVerts;
delete[] iGLNormals;
delete[] iGLTexCoords;
delete[] iGLTris;
m_numJoints = 0;
m_pJoints = NULL;
m_Time = 0;
m_totalTime = 0;
m_looping = true;
skeletoned = false;
restart();
}
//Class Deconstructor
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
72
~Mesh()
{
delete iVertex;
delete iFace;
delete[] iGLVerts;
delete[] iGLNormals;
delete[] iGLTexCoords;
delete[] iGLTris;
if( iTextureObject != 0xffffffff )
glDeleteTextures( 1, &iTextureObject );
TInt i=0;
for ( i = 0; i < m_numJoints; i++ )
{
delete[] m_pJoints[i].m_pRotationKeyframes;
delete[] m_pJoints[i].m_pTranslationKeyframes;
}
m_numJoints = 0;
if ( m_pJoints != NULL )
{
delete[] m_pJoints;
m_pJoints = NULL;
}
m_Time = 0;
m_totalTime = 0;
m_looping = true;
skeletoned = false;
//delete[] m_pTimer;
animation = NULL;
animActive = 0;
}
public:
//
Animation keyframe information
struct Keyframe
{
TInt m_jointIndex;
TInt m_time;
// in milliseconds
TReal m_parameter[3];
};
//
Skeleton bone joint
struct Joint
{
TReal m_localRotation[3];
TReal m_localTranslation[3];
Matrix m_absolute, m_relative;
TInt m_numRotationKeyframes, m_numTranslationKeyframes;
Keyframe *m_pTranslationKeyframes;
Keyframe *m_pRotationKeyframes;
TInt m_currentTranslationKeyframe, m_currentRotationKeyframe;
Matrix m_final;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
73
TInt m_parent;
};
//
Animation Set information
struct AnimationSet
{
TInt initTime;
TInt endTime;
};
public:
// loading method
void Load(const TReal* verts, const TInt* faces, const TReal* textures,
const TReal* normals, TInt nv, TInt nf, TInt textureSize = 256 );
// loading animation method
void LoadAnimationData( TInt totTime, TInt nJoints, const TReal* jointData, const TReal*
keyframeData, const TInt* vertexJointData );
// Drawing method
void Draw();
//Some methods to position, rotate or scale the mesh in 3D space
void SetPosition( TInt x, TInt y, TInt z );
void Rotate( TInt x, TInt y, TInt z );
void Scale( TInt x, TInt y, TInt z );
// Method to set a texture to the mesh
void SetTexture( GLuint iTexture)
{
iTextureObject = iTexture;
}
// Setting Diffuse Material
void SetDiffuseMaterial( TReal r, TReal g, TReal b, TReal a )
{
matDiffuse[0] = (GLfloat)r;
matDiffuse[1] = (GLfloat)g;
matDiffuse[2] = (GLfloat)b;
matDiffuse[3] = (GLfloat)a;
}
// Setting Ambient Material
void SetAmbientMaterial( TReal r, TReal g, TReal b, TReal a )
{
matAmbient[0] = (GLfloat)r;
matAmbient[1] = (GLfloat)g;
matAmbient[2] = (GLfloat)b;
matAmbient[3] = (GLfloat)a;
}
// Setting Specular Material
void SetSpecularMaterial( TReal r, TReal g, TReal b, TReal a )
{
matSpecular[0] = (GLfloat)r;
matSpecular[1] = (GLfloat)g;
matSpecular[2] = (GLfloat)b;
matSpecular[3] = (GLfloat)a;
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
74
// Setting Emission Material
void SetEmissionMaterial( TReal r, TReal g, TReal b, TReal a )
{
matEmission[0] = (GLfloat)r;
matEmission[1] = (GLfloat)g;
matEmission[2] = (GLfloat)b;
matEmission[3] = (GLfloat)a;
}
// Setting Material Shininess
void SetShininess( TInt v )
{
shininess = v;
}
/*
Set the values of a particular keyframe for a particular joint.
jointIndex
The joint to setup the keyframe for
keyframeIndex The maximum number of keyframes
time
The time in milliseconds of the keyframe
parameter
The rotation/translation values for the keyframe
isRotation
Whether it is a rotation or a translation keyframe
*/
void setJointKeyframe( TInt jointIndex, TInt keyframeIndex, TInt time, TReal *parameter, bool
isRotation );
/*
Setup joint matrices. */
void setupJoints();
/*
Set looping factor for animation. */
void setLooping( bool looping ) { m_looping = looping; }
/*
Advance animation by a frame. */
void advanceAnimation();
/*
Restart animation. */
void restart(int n = 0 );
void setAnimationSet(int n = 0 );
// Mesh 3D space information
TInt position[3];
TInt scale[3];
TInt rotation[3];
// Mesh loading data
TVertex* iVertex;
TFace* iFace;
TInt
num_vertices;
TInt
num_faces;
//
Joint information
TInt m_numJoints;
Joint *m_pJoints;
//
Total animation time
TInt m_totalTime;
//
Is the animation looping?
bool m_looping;
//
Is the mesh skeletoned
bool skeletoned;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
75
// an array of different animation to initialize
AnimationSet * animation;
// animation information
int animActive;
bool nothingToDo;
// animation time
TInt m_Time;
// OpenGL ES loading data
GLuint
iTextureObject;
GLfixed*
iGLVerts;
GLfixed*
iGLNormals;
GLfixed*
iGLTexCoords;
TInt
iGLTriCount;
TInt
iGLVertCount;
GLushort*
iGLTris;
// OpenGL ES Material data
GLfloat matDiffuse[4];
GLfloat matAmbient[4];
GLfloat matSpecular[4];
GLfloat matEmission[4];
TInt shininess;
};
Per prima cosa analizziamo il metodo Load(). Questo prende come parametri di
input alcuni array di differenti tipi salvati in un file libreria .h
Per esempio in un file del tipo :
#include "3DObjects.h"
Incluso all’inizio del codice.
Se la mesh non ha uno scheletro ed è semplicemente statica, questi semplici
array contengono tutte le informazioni necessarie per disegnare la mesh
correttamente.
Questi array vengono creati automaticamente con un programma di mia
creazione che prende in input alcuni file di testo opportunamente formattati. La
semplice operazione che bisognerà fare sarà un copia e incolla del file in output
all’interno del famoso file .h.
C’è da notare che I tre file presi in input dal programma di mia creazione non
sono altro che dovuti ad un altra semplice operazione di copia e incolla dal file
in formato MilkShape3D ASCII. E’ da notare che si assume che si usi una mesh
singola e non tante mesh separate è quindi importante avere all’interno del file
mesh un'unica mesh poligonale.
All’interno del primo file “vertices.txt” bisogna copiare tutti i dati dei vertici
come in questo esempio qui sotto:
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
76
// MilkShape 3D ASCII
Frames: 30
Frame: 1
Meshes: 1
"Pikachu" 0 0
513
0 -0.394134 -4.031174 -56.168152 0.738136 0.872696 5
0 -0.339256 -7.681541 -74.948296 0.751427 0.888163 5
…………………………………………………………………………………………….
0 0.606553 0.814919 -99.120064 0.756648 0.852161 5
0 28.248407 44.688095 -5.897087 0.453614 0.806055 2
389
0.994053 -0.106262 0.023818
0.988495 -0.147908 0.031637
0.992406 -0.119851 0.027690
……………………………………………………………
// vertices.txt file
0 -0.394134 -4.031174 -56.168152 0.738136 0.872696 5
0 -0.339256 -7.681541 -74.948296 0.751427 0.888163 5
…………………………………………………………………………………………….
0 0.606553 0.814919 -99.120064 0.756648 0.852161 5
0 28.248407 44.688095 -5.897087 0.453614 0.806055 2
E’ DA NOTARE CHE BISOGNA TENERE IN CONSIDERAZIONE SOLO I
NUMERI COMPRESI TRA IL NUMERO DI VERTICI E QUELLO DELLE
NORMALI (in questo esempio tra 513 e 389). NESSUN ALTRO NUMERO
DEVE COMPARIRE ALL’INTERNO DEL FILE, CHE DEVE TERMINARE
CON UNA LINEA VUOTA O A CAPO.
Nel secondo file “normals.txt” bisogna copiare solo i dati relativi alle normali
come in questo esempio:
// MilkShape 3D ASCII
Frames: 30
Frame: 1
Meshes: 1
"Pikachu" 0 0
513
0 -0.394134 -4.031174 -56.168152 0.738136 0.872696 5
0 -0.339256 -7.681541 -74.948296 0.751427 0.888163 5
……………………………………………………………………………………………
0 0.606553 0.814919 -99.120064 0.756648 0.852161 5
0 28.248407 44.688095 -5.897087 0.453614 0.806055 2
389
0.994053 -0.106262 0.023818
0.988495 -0.147908 0.031637
0.992406 -0.119851 0.027690
……………………………………………………………
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
77
0.857360 0.227740 0.461593
-0.671372 -0.151214 -0.725530
-0.808161 -0.486752 -0.331584
0.799173 -0.534374 -0.275258
380
0 0 1 2 0 1 2 1
0 3 4 5 3 4 5 1
0 5 6 3 5 6 3 1
0 7 8 9 7 7 7 1
………………………………………
// normals.txt file
0.994053 -0.106262 0.023818
0.988495 -0.147908 0.031637
0.992406 -0.119851 0.027690
……………………………………………………………
0.857360 0.227740 0.461593
-0.671372 -0.151214 -0.725530
-0.808161 -0.486752 -0.331584
0.799173 -0.534374 -0.275258
E’ DA NOTARE CHE BISOGNA TENERE IN CONSIDERAZIONE SOLO I
NUMERI COMPRESI TRA IL NUMERO DELLE NORMALI E QUELLO
DELLE FACCE (in questo esempio tra 389 e 380). NESSUN ALTRO
NUMERO DEVE COMPARIRE ALL’INTERNO DEL FILE, CHE DEVE
TERMINARE CON UNA LINEA VUOTA O A CAPO.
Nell’ultimo file “faces.txt” bisogna copiare solo i dati relative alle informazioni
sulle face come nell’esempio sottostante:
// MilkShape 3D ASCII
Frames: 30
Frame: 1
Meshes: 1
"Pikachu" 0 0
513
0 -0.394134 -4.031174 -56.168152 0.738136 0.872696 5
0 -0.339256 -7.681541 -74.948296 0.751427 0.888163 5
……………………………………………………………………………………………
0 0.606553 0.814919 -99.120064 0.756648 0.852161 5
0 28.248407 44.688095 -5.897087 0.453614 0.806055 2
389
0.994053 -0.106262 0.023818
0.988495 -0.147908 0.031637
0.992406 -0.119851 0.027690
……………………………………………………………
0.857360 0.227740 0.461593
-0.671372 -0.151214 -0.725530
-0.808161 -0.486752 -0.331584
0.799173 -0.534374 -0.275258
380
0 0 1 2 0 1 2 1
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
78
0 3 4 5 3 4 5 1
0 5 6 3 5 6 3 1
0 7 8 9 7 7 7 1
………………………………………
0 459 449 448 343 333 332 1
0 496 39 452 374 36 336 1
0 496 414 39 374 298 36 1
Materials: 2
"lambert1"
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000
1.000000
"pikachu.jpg"
0.000000
0.000000
0.000000
0.000000
1.000000
1.000000
1.000000
1.000000
// faces.txt file
0 0 1 2 0 1 2 1
0 3 4 5 3 4 5 1
0 5 6 3 5 6 3 1
0 7 8 9 7 7 7 1
………………………………………
0 459 449 448 343 333 332 1
0 496 39 452 374 36 336 1
0 496 414 39 374 298 36 1
E’ DA NOTARE CHE BISOGNA TENERE IN CONSIDERAZIONE SOLO I
NUMERI COMPRESI TRA IL NUMERO DELLE FACCE E LA PARTE
RELATIVA AI MATERIALI DELLA MESH (in questo esempio tra 380 e
“Material: 2”). NESSUN ALTRO NUMERO DEVE COMPARIRE
ALL’INTERNO DEL FILE, CHE DEVE TERMINARE CON UNA LINEA
VUOTA O A CAPO.
Una volta riempiti I file l’unica operazione rimanente è il doppio click sul file
MESH_DATA.bat e verrà creato un file “outputModel.txt” con il codice
sorgente da copiare ed incollare nell’applicazione stessa.
Questo software MESH_DATA si può scaricare
[http://www.gents.it/ggd/Files/MESH_DATA.zip]
facilmente
qui.
Analizziamo ora come la funzione Load() lavora su questi dati per riempire gli
array con dati utili alle OpenGL ES.
Questo codice sottostante assume un semplice implementazione di classi come
Vertex e Face (non sono necessarie ai fini del funzionamento!!! Io le ho
adoperate per dare maggior chiarezza):
// 23:9 fixed point math used trough all math in 3D-example
const TInt KShift = 9;
const TInt GlShift = 16;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
79
const TInt shift = GlShift - KShift;
// CONSTANTS
const TUint KInvalidTextureObject = 0xffffffff;
void Mesh::Load(const TReal* verts, const TInt* faces, const TReal* textures,
const TReal* normals, TInt nv, TInt nf, TInt textureSize )
{
// filling mesh information data with arrays numbers
iVertex = new TVertex[nv];
iFace = new TFace[nf];
num_vertices = nv;
num_faces = nf;
TInt i=0;
TInt v=0, t=0, n=0;
for(i=0; i<nv; i++)
{
iVertex[i] = TVertex( (TInt)verts[v]*100, (TInt)verts[v+1]*100, (TInt)verts[v+2]*100,
(TInt)textures[t], (TInt)textures[t+1],
(TInt)normals[n], (TInt)normals[n+1],
(TInt)normals[n+2] );
v = v+3;
t = t+2;
n = n+3;
}
v=0;
for(i=0; i<nf; i++)
{
iFace[i] = TFace( faces[v], faces[v+1], faces[v+2] );
iFace[i].normalX = iVertex[iFace[i].iV1].normalX +
iVertex[iFace[i].iV2].normalX +
iVertex[iFace[i].iV3].normalX;
iFace[i].normalY = iVertex[iFace[i].iV1].normalY +
iVertex[iFace[i].iV2].normalY +
iVertex[iFace[i].iV3].normalY;
iFace[i].normalZ = iVertex[iFace[i].iV1].normalZ +
iVertex[iFace[i].iV2].normalZ +
iVertex[iFace[i].iV3].normalZ;
v = v+3;
}
// delete OpenGL ES data and create new
delete[] iGLVerts;
delete[] iGLNormals;
delete[] iGLTexCoords;
delete[] iGLTris;
iGLTriCount = nf*3;
iGLVerts=new GLfixed[ iGLTriCount*3 ];
iGLTexCoords=new GLfixed[ iGLTriCount*2 ];
iGLTris=new GLushort[ iGLTriCount ];
iGLNormals=new GLfixed[ iGLTriCount*3 ];
TInt ic=0;
TInt vc=0;
// filling OpenGL ES with mesh information data
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
80
for (i=0;i<nf;i++)
{
TInt a,b,c;
a=iFace[i].iV1;
b=iFace[i].iV2;
c=iFace[i].iV3;
iGLVerts[vc*3] = iVertex[a].iX << shift;
iGLVerts[vc*3+1] = iVertex[a].iY << shift;
iGLVerts[vc*3+2] = iVertex[a].iZ << shift;
iGLNormals[vc*3] = iVertex[a].normalX << shift;
iGLNormals[vc*3+1] = iVertex[a].normalY << shift;
iGLNormals[vc*3+2] = iVertex[a].normalZ << shift;
iGLTexCoords[vc*2] = ( iVertex[a].iTx << GlShift ) / textureSize;
iGLTexCoords[vc*2+1] = ( iVertex[a].iTy << GlShift ) / textureSize;
iGLTris[ic] = (GLushort)vc;
ic++;
vc++;
iGLVerts[vc*3] = iVertex[b].iX << shift;
iGLVerts[vc*3+1] = iVertex[b].iY << shift;
iGLVerts[vc*3+2] = iVertex[b].iZ << shift;
iGLNormals[vc*3] = iVertex[b].normalX << shift;
iGLNormals[vc*3+1] = iVertex[b].normalY << shift;
iGLNormals[vc*3+2] = iVertex[b].normalZ << shift;
iGLTexCoords[vc*2] = ( iVertex[b].iTx << GlShift ) / textureSize;
iGLTexCoords[vc*2+1] = ( iVertex[b].iTy << GlShift ) / textureSize;
iGLTris[ic] = (GLushort)vc;
ic++;
vc++;
iGLVerts[vc*3] = iVertex[c].iX << shift;
iGLVerts[vc*3+1] = iVertex[c].iY << shift;
iGLVerts[vc*3+2] = iVertex[c].iZ << shift;
iGLNormals[vc*3] = iVertex[c].normalX << shift;
iGLNormals[vc*3+1] = iVertex[c].normalY << shift;
iGLNormals[vc*3+2] = iVertex[c].normalZ << shift;
iGLTexCoords[vc*2] = ( iVertex[c].iTx << GlShift) / textureSize;
iGLTexCoords[vc*2+1] = ( iVertex[c].iTy << GlShift) / textureSize;
iGLTris[ic] = (GLushort)vc;
ic++;
vc++;
}
// assign an invalid texture object
iTextureObject = KInvalidTextureObject;
// set a standard white material
int l=0;
for(l=0; l<4; l++)
{
matDiffuse[l] = 1.0;
matAmbient[l] = 1.0;
matSpecular[l] = 1.0;
matEmission[l] = 1.0;
}
shininess = 0;
visible = true;
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
81
Fatto ciò rimane solo da settare una texture per la mesh e poi disegnarla.
Effettuare questa assegnazione è molto semplice. Ciò che appare più difficile è
come caricare immagini bitmap o jpeg, ma questo non è parte di interesse in
questo articolo. Si assumerà quindi la presenza di un oggetto del tipo GLuint
iTexture:
void SetTexture( GLuint iTexture)
{
iTextureObject = iTexture;
}
Ora si necessita solo di disegnare il tutto sullo schermo. Nella implementazione
sottostante appaiono anche casi relativi alle mesh non statiche ma già con uno
scheletro. Quello che dovrete fare ora è solo saltare queste parti per tornarci poi
successivamente con calma quando avrò spiegato con più chiarezza il processo
di caricamento delle informazioni per l’animazione.
void Mesh::Draw()
{
TInt vc=0;
// for all faces move and rotate vertices in 3D space
for ( TInt j = 0; j < num_faces; j++ )
{
if ( skeletoned && iVertex[iFace[j].iV1].m_boneID >= 0 )
{
// rotate according to transformation matrix
const Matrix& final = m_pJoints[iVertex[iFace[j].iV1].m_boneID].m_final;
TReal m_vertexNormals[3];
m_vertexNormals[0] = iVertex[iFace[j].iV1].normalX;
m_vertexNormals[1] = iVertex[iFace[j].iV1].normalY;
m_vertexNormals[2] = iVertex[iFace[j].iV1].normalZ;
Vector newNormal( m_vertexNormals );
newNormal.transform3( final );
iGLNormals[vc*3] = (TInt)newNormal.m_vector[0] << shift;
iGLNormals[vc*3+1] = (TInt)newNormal.m_vector[1] << shift;
iGLNormals[vc*3+2] = (TInt)newNormal.m_vector[2] << shift;
TReal m_location[3];
m_location[0] = iVertex[iFace[j].iV1].iX;
m_location[1] = iVertex[iFace[j].iV1].iY;
m_location[2] = iVertex[iFace[j].iV1].iZ;
Vector newVertex( m_location );
newVertex.transform( final );
iGLVerts[vc*3] = (TInt)newVertex.m_vector[0] << shift;
iGLVerts[vc*3+1] = (TInt)newVertex.m_vector[1] << shift;
iGLVerts[vc*3+2] = (TInt)newVertex.m_vector[2] << shift;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
82
}
else
{
iGLVerts[vc*3] = iVertex[iFace[j].iV1].iX << shift;
iGLVerts[vc*3+1] = iVertex[iFace[j].iV1].iY << shift;
iGLVerts[vc*3+2] = iVertex[iFace[j].iV1].iZ << shift;
iGLNormals[vc*3] = iVertex[iFace[j].iV1].normalX << shift;
iGLNormals[vc*3+1] = iVertex[iFace[j].iV1].normalY << shift;
iGLNormals[vc*3+2] = iVertex[iFace[j].iV1].normalZ << shift;
}
vc++;
if ( skeletoned && iVertex[iFace[j].iV2].m_boneID >= 0 )
{
// rotate according to transformation matrix
const Matrix& final = m_pJoints[iVertex[iFace[j].iV2].m_boneID].m_final;
TReal m_vertexNormals[3];
m_vertexNormals[0] = iVertex[iFace[j].iV2].normalX;
m_vertexNormals[1] = iVertex[iFace[j].iV2].normalY;
m_vertexNormals[2] = iVertex[iFace[j].iV2].normalZ;
Vector newNormal( m_vertexNormals );
newNormal.transform3( final );
iGLNormals[vc*3] = (TInt)newNormal.m_vector[0] << shift;
iGLNormals[vc*3+1] = (TInt)newNormal.m_vector[1] << shift;
iGLNormals[vc*3+2] = (TInt)newNormal.m_vector[2] << shift;
TReal m_location[3];
m_location[0] = iVertex[iFace[j].iV2].iX;
m_location[1] = iVertex[iFace[j].iV2].iY;
m_location[2] = iVertex[iFace[j].iV2].iZ;
Vector newVertex( m_location );
newVertex.transform( final );
iGLVerts[vc*3] = (TInt)newVertex.m_vector[0] << shift;
iGLVerts[vc*3+1] = (TInt)newVertex.m_vector[1] << shift;
iGLVerts[vc*3+2] = (TInt)newVertex.m_vector[2] << shift;
}
else
{
iGLVerts[vc*3] = iVertex[iFace[j].iV2].iX << shift;
iGLVerts[vc*3+1] = iVertex[iFace[j].iV2].iY << shift;
iGLVerts[vc*3+2] = iVertex[iFace[j].iV2].iZ << shift;
iGLNormals[vc*3] = iVertex[iFace[j].iV2].normalX << shift;
iGLNormals[vc*3+1] = iVertex[iFace[j].iV2].normalY << shift;
iGLNormals[vc*3+2] = iVertex[iFace[j].iV2].normalZ << shift;
}
vc++;
if ( skeletoned && iVertex[iFace[j].iV3].m_boneID >= 0 )
{
// rotate according to transformation matrix
const Matrix& final = m_pJoints[iVertex[iFace[j].iV3].m_boneID].m_final;
TReal m_vertexNormals[3];
m_vertexNormals[0] = iVertex[iFace[j].iV3].normalX;
m_vertexNormals[1] = iVertex[iFace[j].iV3].normalY;
m_vertexNormals[2] = iVertex[iFace[j].iV3].normalZ;
Vector newNormal( m_vertexNormals );
newNormal.transform3( final );
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
83
iGLNormals[vc*3] = (TInt)newNormal.m_vector[0] << shift;
iGLNormals[vc*3+1] = (TInt)newNormal.m_vector[1] << shift;
iGLNormals[vc*3+2] = (TInt)newNormal.m_vector[2] << shift;
TReal m_location[3];
m_location[0] = iVertex[iFace[j].iV3].iX;
m_location[1] = iVertex[iFace[j].iV3].iY;
m_location[2] = iVertex[iFace[j].iV3].iZ;
Vector newVertex( m_location );
newVertex.transform( final );
iGLVerts[vc*3] = (TInt)newVertex.m_vector[0] << shift;
iGLVerts[vc*3+1] = (TInt)newVertex.m_vector[1] << shift;
iGLVerts[vc*3+2] = (TInt)newVertex.m_vector[2] << shift;
}
else
{
iGLVerts[vc*3] = iVertex[iFace[j].iV3].iX << shift;
iGLVerts[vc*3+1] = iVertex[iFace[j].iV3].iY << shift;
iGLVerts[vc*3+2] = iVertex[iFace[j].iV3].iZ << shift;
iGLNormals[vc*3] = iVertex[iFace[j].iV3].normalX << shift;
iGLNormals[vc*3+1] = iVertex[iFace[j].iV3].normalY << shift;
iGLNormals[vc*3+2] = iVertex[iFace[j].iV3].normalZ << shift;
}
vc++;
}
// begin OpenGL ES drawing phase
glMatrixMode(GL_MODELVIEW);
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FIXED, 0, iGLVerts );
glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer( GL_FIXED, 0, iGLNormals );
// check if the mesh is textured
if( iTextureObject != KInvalidTextureObject )
{
glBindTexture( GL_TEXTURE_2D, iTextureObject );
glEnable( GL_TEXTURE_2D );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FIXED, 0, iGLTexCoords );
}
else
{
glDisable( GL_TEXTURE_2D );
glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
}
// Set mesh material
glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse );
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient );
glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular );
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, matEmission );
glMaterialx(
GL_FRONT_AND_BACK, GL_SHININESS, shininess << 16 );
// draw all mesh data
glColor4x( 255.f, 255.f, 255.f, 255.f ); //White
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glDrawElements( GL_TRIANGLES, iGLTriCount, GL_UNSIGNED_SHORT, iGLTris );
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
84
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY );
}
Ora possiamo usare tutti i metodi sopra descritti per caricare e disegnare la
mesh sullo schermo come in questo esempio:
// Set the screen background color.
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
/* Make OpenGL ES automatically normalize all normals after tranformations.
This is important when making irregular xforms like scaling, or if we
have specified nonunit-length normals. */
glEnable( GL_NORMALIZE );
// Initialize viewport and projection.
glViewport( 0, 0, iScreenWidth, iScreenHeight );
glMatrixMode( GL_PROJECTION );
glFrustumf( -1.f, 1.f, -1.f, 1.f, 3.f, 1000.f );
glMatrixMode( GL_MODELVIEW );
Ambient.Load( KAmbientVertexData,
KAmbientFaceData,
KAmbientTextureData, KAmbientNormalData,
KNumAmbientVertices, KNumAmbientFaces, 256 );
Ambient.SetAmbientMaterial( 0.8, 0.8, 0.8, 1.0 );
Ambient.SetDiffuseMaterial( 0.8, 0.8, 0.8, 1.0 );
Ambient.SetEmissionMaterial( 0.8, 0.8, 0.8, 1.0 );
Ambient.SetSpecularMaterial( 0.8, 0.2, 0.4, 1.0 );
Ambient.SetShininess( 1 );
Ambient.SetTexture( iTexObjects[1] );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glShadeModel( GL_SMOOTH );
// Set the screen background color.
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glLoadIdentity();
//Draw
glPushMatrix();
Ambient.SetPosition( 0, 0, -100 );
Ambient.Scale( 15, 4, 15 );
Ambient.Draw();
glPopMatrix();
E questo è tutto per quanto riguarda le mesh statiche.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
85
Ora immagino che starete dicendo qualcosa del tipo: “vorrà farci sapere
qualcosa sulle mesh animate con scheletro, spero”. Beh… OK!!!
Per prima cosa bisogna ottenere in qualche modo le informazioni riguardanti
ossa e keyframes dal file in formato MilkShape3D ASCII. Ma anche questa
operazione apparirà molto semplice in quanto ho creato un altro piccolo
programma che renderà tutto semplice ed intuitivo, per permettere ancora una
volta di effettuare un veloce copia e incolla nel file .h.
Basterà seguire delle semplici istruzioni come nell’esempio qui sotto:
//MilkShape 3D ASCII
……………………………………………………………………
QUI CI SONO I DATI SUI MATERIALI
……………………………………………………………………
Bones: 10
"joint1"
""
16 -9.000000 -41.788368 -28.533302 0.000000 0.000000 0.000000
2
1.000000 0.000000 0.000000 0.000000
30.000000 0.000000 0.000000 0.000000
2
1.000000 0.000000 0.000000 0.000000
30.000000 0.000000 0.000000 0.000000
"joint2"
"joint1"
16 0.527245 21.499857 38.500114 0.000000 0.000000 0.000000
7
1.000000 0.000000 0.000000 0.000000
10.000000 0.000000 0.000000 0.000000
12.000000 0.000000 0.000000 0.000000
………………………………………………………………………………………………
………………………………………………………………………………………………
………………………………………………………………………………………………
20.000000 -0.418879 0.000000 0.000000
30.000000 0.000000 0.000000 0.000000
GroupComments: 0
MaterialComments: 0
//joints.txt file
Bones: 10
"joint1"
""
16 -9.000000 -41.788368 -28.533302 0.000000 0.000000 0.000000
2
1.000000 0.000000 0.000000 0.000000
30.000000 0.000000 0.000000 0.000000
2
1.000000 0.000000 0.000000 0.000000
30.000000 0.000000 0.000000 0.000000
"joint2"
"joint1"
16 0.527245 21.499857 38.500114 0.000000 0.000000 0.000000
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
86
7
1.000000 0.000000 0.000000 0.000000
10.000000 0.000000 0.000000 0.000000
12.000000 0.000000 0.000000 0.000000
………………………………………………………………………………………………
………………………………………………………………………………………………
………………………………………………………………………………………………
20.000000 -0.418879 0.000000 0.000000
30.000000 0.000000 0.000000 0.000000
E’ DA NOTARE CHE BISOGNA TENERE IN CONSIDERAZIONE SOLO LE
LINEE COMPRESE TRA IL NUMERO DI OSSA E LA PARTE RELATIVA
ALLE ULTIME NOTE (in questo esempio tra “Bones: 10” e
“GroupComments: 0”). NESSUN ALTRO NUMERO DEVE COMPARIRE
ALL’INTERNO DEL FILE, CHE DEVE TERMINARE CON UNA LINEA
VUOTA O A CAPO.
Una volt ache il file “joints.txt” sarà stato riempito, basterà effettuare un doppio
click sull’eseguibile SKELETON_DATA.bat e due file ( “JointsData.txt” e
“KeyframesData.txt” ) verranno create con il codice sorgente da includere
direttamente nell’applicazione.
Questo software SKELETON_DATA si può scaricare
[http://www.gents.it/ggd/Files/SKELETON_DATA.zip]
facilmente
qui.
Analizziamo ora come la funzione LoadAnimationData() lavora con questi dati
direttamente.
Questo codice, sotto presentato, presuppone l’utilizzo di specifiche classi come
Matrix, Quaternion e Vector (maggiori informazioni si possono trovare a questo
indirizzo http://rsn.gamedev.net/tutorials/ms3danim.asp ) :
void Mesh::LoadAnimationData( TInt totTime, TInt nJoints, const TReal* jointData, const TReal*
keyframeData, const TInt* vertexJointData )
{
// Let us know that we want to draw a skinned mesh
skeletoned = true;
// set total length of the animation
m_totalTime = totTime*1000;
// set number of joints
m_numJoints = nJoints;
m_pJoints = new Joint[m_numJoints];
TInt i = 0;
// fill vertices structure with bone associated
for(i=0; i<num_vertices; i++)
iVertex[i].m_boneID = vertexJointData[i];
TInt j=0;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
87
TInt k=0;
// for every joint fill keyframe data
for ( i = 0; i < nJoints; i++ )
{
j++;
m_pJoints[i].m_parent = (TInt)jointData[j];
j++;
m_pJoints[i].m_localTranslation[0] = (TInt)jointData[j] << shift;
j++;
m_pJoints[i].m_localTranslation[1] = (TInt)jointData[j] << shift;
j++;
m_pJoints[i].m_localTranslation[2] = (TInt)jointData[j] << shift;
j++;
m_pJoints[i].m_localRotation[0] = jointData[j];
j++;
m_pJoints[i].m_localRotation[1] = jointData[j];
j++;
m_pJoints[i].m_localRotation[2] = jointData[j];
j++;
k++;
TInt l = 0;
m_pJoints[i].m_numTranslationKeyframes = (TInt)keyframeData[k];
m_pJoints[i].m_pTranslationKeyframes = new
Keyframe[(TInt)keyframeData[k]];
k++;
for ( l = 0; l < m_pJoints[i].m_numTranslationKeyframes; l++ )
{
TInt time = keyframeData[k];
k++;
TReal m_parameter[3];
m_parameter[0] = (TInt)keyframeData[k] << shift;
k++;
m_parameter[1] = (TInt)keyframeData[k] << shift;
k++;
m_parameter[2] = (TInt)keyframeData[k] << shift;
k++;
setJointKeyframe( i, l, time*1000, m_parameter, false );
}
m_pJoints[i].m_numRotationKeyframes = (TInt)keyframeData[k];
m_pJoints[i].m_pRotationKeyframes = new
Keyframe[(TInt)keyframeData[k]];
k++;
for ( l = 0; l < m_pJoints[i].m_numRotationKeyframes; l++ )
{
TInt time = keyframeData[k];
k++;
TReal m_parameter[3];
m_parameter[0] = keyframeData[k];
k++;
m_parameter[1] = keyframeData[k];
k++;
m_parameter[2] = keyframeData[k];
k++;
setJointKeyframe( i, l, time*1000, m_parameter, true );
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
88
}
setupJoints();
animActive = 0;
nothingToDo = false;
restart(animActive);
jointData = NULL;
keyframeData = NULL;
vertexJointData = NULL;
}
Potete notare che questo metodo sopra descritto fa uso di alcune funzioni.
Mostrerò di seguito il loro codice:
void Mesh::setJointKeyframe( TInt jointIndex, TInt keyframeIndex, TInt time, TReal *parameter, bool
isRotation )
{
// fill keyframe data for a single joint with some parameter passed in input at this function
Keyframe& keyframe = isRotation ?
m_pJoints[jointIndex].m_pRotationKeyframes[keyframeIndex] :
m_pJoints[jointIndex].m_pTranslationKeyframes[keyframeIndex];
keyframe.m_jointIndex = jointIndex;
keyframe.m_time = time;
keyframe.m_parameter[0] = parameter[0];
keyframe.m_parameter[1] = parameter[1];
keyframe.m_parameter[2] = parameter[2];
}
void Mesh::setupJoints()
{
// this function set up every joint to their initial position so to have all dependencies working well
TInt i=0;
for ( i = 0; i < m_numJoints; i++ )
{
Joint& joint = m_pJoints[i];
// we set rotation and translation for every koint
joint.m_relative.setRotationRadians( joint.m_localRotation );
joint.m_relative.setTranslation( joint.m_localTranslation );
// and modify them if it’s not a leaf node
if ( joint.m_parent >= 0 )
{
joint.m_absolute.set( m_pJoints[joint.m_parent].m_absolute.m_matrix );
joint.m_absolute.postMultiply( joint.m_relative );
}
else
joint.m_absolute.set( joint.m_relative.m_matrix );
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
89
// move every vertices accordingly to koint transformations
for ( i = 0; i < num_vertices; i++ )
{
if ( iVertex[i].m_boneID >= 0 )
{
const Matrix& matrix = m_pJoints[iVertex[i].m_boneID].m_absolute;
TReal m_location[3];
m_location[0] = iVertex[i].iX;
m_location[1] = iVertex[i].iY;
m_location[2] = iVertex[i].iZ;
matrix.inverseTranslateVect( m_location );
matrix.inverseRotateVect( m_location );
iVertex[i].iX = (TInt)m_location[0];
iVertex[i].iY = (TInt)m_location[1];
iVertex[i].iZ = (TInt)m_location[2];
TReal m_vertexNormals[3];
m_vertexNormals[0] = iVertex[i].normalX;
m_vertexNormals[1] = iVertex[i].normalY;
m_vertexNormals[2] = iVertex[i].normalZ;
matrix.inverseRotateVect( m_vertexNormals );
iVertex[i].normalX = (TInt)m_vertexNormals[0];
iVertex[i].normalY = (TInt)m_vertexNormals[1];
iVertex[i].normalZ = (TInt)m_vertexNormals[2];
}
}
}
// This function let us to set the animation number n from the beginning. It supposes that we’ve initialized
the AnimationSet array of Mesh class in another part of our code
void Mesh::restart(int n)
{
for ( TInt i = 0; i < m_numJoints; i++ )
{
m_pJoints[i].m_currentRotationKeyframe =
m_pJoints[i].m_currentTranslationKeyframe = 0;
m_pJoints[i].m_final.set( m_pJoints[i].m_absolute.getMatrix());
}
if(n==0)
m_Time = 0;
else
m_Time = animation[n].initTime*1000;
nothingToDo = false;
}
// This function works almost as restart method but in this we set animActive variable
void Mesh::setAnimationSet(int n)
{
animActive = n;
for ( TInt i = 0; i < m_numJoints; i++ )
{
m_pJoints[i].m_currentRotationKeyframe =
m_pJoints[i].m_currentTranslationKeyframe = 0;
m_pJoints[i].m_final.set( m_pJoints[i].m_absolute.getMatrix());
}
m_Time = animation[n].initTime*1000;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
90
nothingToDo = false;
}
// This function is the core of all animation. We have to call this method befor drawing our mesh or it’ll
seem us static
void Mesh::advanceAnimation()
{
// let time pass
m_Time += 1000;
TInt time = m_Time;
// Here we check if we have to restart our animation if it haven’t to loop
if ( time > animation[animActive].endTime*1000 )
{
if ( m_looping )
{
restart(animActive);
time = animation[animActive].initTime*1000;
}
else
{
time = animation[animActive].endTime*1000;
nothingToDo = true;
}
}
// Now we set all transformation following keyframe transformation parameters
for ( TInt i = 0; i < m_numJoints; i++ )
{
TReal transVec[3];
Matrix transform;
TInt frame;
Joint *pJoint = &m_pJoints[i];
if ( pJoint->m_numRotationKeyframes == 0 && pJoint->m_numTranslationKeyframes
== 0 )
{
pJoint->m_final.set( pJoint->m_absolute.getMatrix());
continue;
}
frame = pJoint->m_currentTranslationKeyframe;
while ( frame < pJoint->m_numTranslationKeyframes && pJoint>m_pTranslationKeyframes[frame].m_time < time )
{
frame++;
}
pJoint->m_currentTranslationKeyframe = frame;
if ( frame == 0 ){
transVec[0] = pJoint->m_pTranslationKeyframes[0].m_parameter[0];
transVec[1] = pJoint->m_pTranslationKeyframes[0].m_parameter[1];
transVec[2] = pJoint->m_pTranslationKeyframes[0].m_parameter[2];
}
else if ( frame == pJoint->m_numTranslationKeyframes ){
transVec[0] = pJoint->m_pTranslationKeyframes[frame-1].m_parameter[0];
transVec[1] = pJoint->m_pTranslationKeyframes[frame-1].m_parameter[1];
transVec[2] = pJoint->m_pTranslationKeyframes[frame-1].m_parameter[2];
}
else
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
91
{
const Mesh::Keyframe& curFrame = pJoint>m_pTranslationKeyframes[frame];
const Mesh::Keyframe& prevFrame = pJoint>m_pTranslationKeyframes[frame-1];
TReal timeDelta = curFrame.m_time-prevFrame.m_time;
TReal interpValue = ( TReal )(( time-prevFrame.m_time )/timeDelta );
transVec[0] = (prevFrame.m_parameter[0]+( curFrame.m_parameter[0]prevFrame.m_parameter[0] )*interpValue);
transVec[1] = (prevFrame.m_parameter[1]+( curFrame.m_parameter[1]prevFrame.m_parameter[1] )*interpValue);
transVec[2] = (prevFrame.m_parameter[2]+( curFrame.m_parameter[2]prevFrame.m_parameter[2] )*interpValue);
}
frame = pJoint->m_currentRotationKeyframe;
while ( frame < pJoint->m_numRotationKeyframes && pJoint>m_pRotationKeyframes[frame].m_time < time )
{
frame++;
}
pJoint->m_currentRotationKeyframe = frame;
if ( frame == 0 )
transform.setRotationRadians( pJoint>m_pRotationKeyframes[0].m_parameter );
else if ( frame == pJoint->m_numRotationKeyframes )
transform.setRotationRadians( pJoint->m_pRotationKeyframes[frame1].m_parameter );
else
{
const Mesh::Keyframe& curFrame = pJoint->m_pRotationKeyframes[frame];
const Mesh::Keyframe& prevFrame = pJoint->m_pRotationKeyframes[frame1];
TReal timeDelta = curFrame.m_time-prevFrame.m_time;
TReal interpValue = ( TReal )(( time-prevFrame.m_time )/timeDelta );
TReal rotVec[3];
rotVec[0] = prevFrame.m_parameter[0]+( curFrame.m_parameter[0]prevFrame.m_parameter[0] )*interpValue;
rotVec[1] = prevFrame.m_parameter[1]+( curFrame.m_parameter[1]prevFrame.m_parameter[1] )*interpValue;
rotVec[2] = prevFrame.m_parameter[2]+( curFrame.m_parameter[2]prevFrame.m_parameter[2] )*interpValue;
transform.setRotationRadians( rotVec );
}
transform.setTranslation( transVec );
Matrix relativeFinal( pJoint->m_relative );
relativeFinal.postMultiply( transform );
if ( pJoint->m_parent < 0 )
pJoint->m_final.set( relativeFinal.getMatrix());
else
{
pJoint->m_final.set( m_pJoints[pJoint->m_parent].m_final.getMatrix());
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
92
pJoint->m_final.postMultiply( relativeFinal );
}
}
}
Se pensate che sia troppo complicato quanto visto fino ad ora vi stupirete per
quanto semplice sia usare i metodi fino ad ora descritti:
Food.LoadAnimationData( 3, NumFoodBones, KFoodJointsData, KFoodKeyframeData,
KFoodVertexJointData );
Food.animation = new Mesh::AnimationSet[3];
Food.animation[0].initTime = 1;
Food.animation[0].endTime = 1;
Food.animation[1].initTime = 2;
Food.animation[1].endTime = 2;
Food.animation[2].initTime = 3;
Food.animation[2].endTime = 3;
Food.setAnimationSet( 0 );
Food.setLooping( false );
Food.visible = false;
Food.SetPosition( -32, -73, 24 );
Food.SetTexture( iTexObjects[12] );
glPushMatrix();
Food.SetPosition( Food.position[0], Food.position[1], Food.position[2] );
Food.advanceAnimation();
Food.Draw();
glPopMatrix();
Spero di essere stato chiaro ed esaudiente e che non ci siano particolari
problemi. Nel caso dovessero essercene visitate pure il mio sito web
http://www.gents.it/ggd/ o scrivetemi le vostre perplessitò a questo indirizzo
e-mail [email protected]
Potrete trovare del codice sorgente qui.
[http://www.gents.it/ggd/Files/SOURCE_CODE.zip]
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
93
7.2 Appendice B
Verrà qui presentato il codice necessario per ricreare, in applicazioni che
gestiscono poligoni tridimensionali, le matrici, i quaternioni e i vettori e le loro
rispettive operazioni.
Implementazioni matematiche
- Matrix.h class Matrix
{
public:
/*
Constructor. */
Matrix();
/*
Destructor. */
~Matrix();
/*
Set to identity. */
void loadIdentity();
/*
Set the values of the matrix. */
void set( const TReal *matrix );
/*
Post-multiply by another matrix. */
void postMultiply( const Matrix& matrix );
/*
Set the translation of the current matrix. Will erase any previous values. */
void setTranslation( const TReal *translation );
/*
Set the inverse translation of the current matrix. Will erase any previous values.
*/
void setInverseTranslation( const TReal *translation );
/*
Make a rotation matrix from Euler angles. The 4th row and column are
unmodified. */
void setRotationRadians( const TReal *angles );
/*
Make a rotation matrix from Euler angles. The 4th row and column are
unmodified. */
void setRotationDegrees( const TReal *angles );
/*
Make a rotation matrix from a quaternion. The 4th row and column are
unmodified. */
void setRotationQuaternion( const Quaternion& quat );
/*
Make an inverted rotation matrix from Euler angles. The 4th row and column
are unmodified. */
void setInverseRotationRadians( const TReal *angles );
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
94
/*
Make an inverted rotation matrix from Euler angles. The 4th row and column
are unmodified. */
void setInverseRotationDegrees( const TReal *angles );
/*
Get the matrix data. */
const TReal *getMatrix() const { return m_matrix; }
/*
Translate a vector by the inverse of the translation part of this matrix. */
void inverseTranslateVect( TReal *pVect ) const;
/*
Rotate a vector by the inverse of the rotation part of this matrix. */
void inverseRotateVect( TReal *pVect ) const;
public:
//
Matrix data, stored in column-major order
TReal m_matrix[16];
};
inline void Matrix::set( const TReal *matrix )
{
for(TInt i=0; i<16; i++)
m_matrix[i] = matrix[i];
}
inline void Matrix::loadIdentity()
{
for(TInt i=0; i<16; i++)
m_matrix[i] = 0;
m_matrix[0] = m_matrix[5] = m_matrix[10] = m_matrix[15] = 1;
}
inline void Matrix::inverseRotateVect( TReal *pVect ) const
{
TReal vec[3];
vec[0] = pVect[0]*m_matrix[0]+pVect[1]*m_matrix[1]+pVect[2]*m_matrix[2];
vec[1] = pVect[0]*m_matrix[4]+pVect[1]*m_matrix[5]+pVect[2]*m_matrix[6];
vec[2] = pVect[0]*m_matrix[8]+pVect[1]*m_matrix[9]+pVect[2]*m_matrix[10];
pVect[0] = vec[0];
pVect[1] = vec[1];
pVect[2] = vec[2];
}
inline void Matrix::inverseTranslateVect( TReal *pVect ) const
{
pVect[0] = pVect[0]-m_matrix[12];
pVect[1] = pVect[1]-m_matrix[13];
pVect[2] = pVect[2]-m_matrix[14];
}
- Matrix.cpp -
Matrix::Matrix()
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
95
{
loadIdentity();
}
Matrix::~Matrix()
{
}
void Matrix::postMultiply( const Matrix& matrix )
{
TReal newMatrix[16];
const TReal *m1 = m_matrix, *m2 = matrix.m_matrix;
newMatrix[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2];
newMatrix[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2];
newMatrix[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2];
newMatrix[3] = 0;
newMatrix[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6];
newMatrix[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6];
newMatrix[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6];
newMatrix[7] = 0;
newMatrix[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10];
newMatrix[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10];
newMatrix[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10];
newMatrix[11] = 0;
newMatrix[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12];
newMatrix[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13];
newMatrix[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14];
newMatrix[15] = 1;
set( newMatrix );
}
void Matrix::setTranslation( const TReal *translation )
{
m_matrix[12] = translation[0];
m_matrix[13] = translation[1];
m_matrix[14] = translation[2];
}
void Matrix::setInverseTranslation( const TReal *translation )
{
m_matrix[12] = -translation[0];
m_matrix[13] = -translation[1];
m_matrix[14] = -translation[2];
}
void Matrix::setRotationDegrees( const TReal *angles )
{
TReal vec[3];
vec[0] = ( TReal )( angles[0]*180.0/PI );
vec[1] = ( TReal )( angles[1]*180.0/PI );
vec[2] = ( TReal )( angles[2]*180.0/PI );
setRotationRadians( vec );
}
void Matrix::setInverseRotationDegrees( const TReal *angles )
{
TReal vec[3];
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
96
vec[0] = ( TReal )( angles[0]*180.0/PI );
vec[1] = ( TReal )( angles[1]*180.0/PI );
vec[2] = ( TReal )( angles[2]*180.0/PI );
setInverseRotationRadians( vec );
}
void Matrix::setRotationRadians( const TReal *angles )
{
TReal cr, sr, cp, sp, cy, sy;
Math::Cos( cr, angles[0] );
Math::Sin( sr, angles[0] );
Math::Cos( cp, angles[1] );
Math::Sin( sp, angles[1] );
Math::Cos( cy, angles[2] );
Math::Sin( sy, angles[2] );
m_matrix[0] = ( TReal )( cp*cy );
m_matrix[1] = ( TReal )( cp*sy );
m_matrix[2] = ( TReal )( -sp );
TReal srsp = sr*sp;
TReal crsp = cr*sp;
m_matrix[4] = ( TReal )( srsp*cy-cr*sy );
m_matrix[5] = ( TReal )( srsp*sy+cr*cy );
m_matrix[6] = ( TReal )( sr*cp );
m_matrix[8] = ( TReal )( crsp*cy+sr*sy );
m_matrix[9] = ( TReal )( crsp*sy-sr*cy );
m_matrix[10] = ( TReal )( cr*cp );
}
void Matrix::setInverseRotationRadians( const TReal *angles )
{
TReal cr, sr, cp, sp, cy, sy;
Math::Cos( cr, angles[0] );
Math::Sin( sr, angles[0] );
Math::Cos( cp, angles[1] );
Math::Sin( sp, angles[1] );
Math::Cos( cy, angles[2] );
Math::Sin( sy, angles[2] );
m_matrix[0] = ( TReal )( cp*cy );
m_matrix[4] = ( TReal )( cp*sy );
m_matrix[8] = ( TReal )( -sp );
TReal srsp = sr*sp;
TReal crsp = cr*sp;
m_matrix[1] = ( TReal )( srsp*cy-cr*sy );
m_matrix[5] = ( TReal )( srsp*sy+cr*cy );
m_matrix[9] = ( TReal )( sr*cp );
m_matrix[2] = ( TReal )( crsp*cy+sr*sy );
m_matrix[6] = ( TReal )( crsp*sy-sr*cy );
m_matrix[10] = ( TReal )( cr*cp );
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
97
void Matrix::setRotationQuaternion( const Quaternion& quat )
{
m_matrix[0] = ( TReal )( 1.0 - 2.0*quat[1]*quat[1] - 2.0*quat[2]*quat[2] );
m_matrix[1] = ( TReal )( 2.0*quat[0]*quat[1] + 2.0*quat[3]*quat[2] );
m_matrix[2] = ( TReal )( 2.0*quat[0]*quat[2] - 2.0*quat[3]*quat[1] );
m_matrix[4] = ( TReal )( 2.0*quat[0]*quat[1] - 2.0*quat[3]*quat[2] );
m_matrix[5] = ( TReal )( 1.0 - 2.0*quat[0]*quat[0] - 2.0*quat[2]*quat[2] );
m_matrix[6] = ( TReal )( 2.0*quat[1]*quat[2] + 2.0*quat[3]*quat[0] );
m_matrix[8] = ( TReal )( 2.0*quat[0]*quat[2] + 2.0*quat[3]*quat[1] );
m_matrix[9] = ( TReal )( 2.0*quat[1]*quat[2] - 2.0*quat[3]*quat[0] );
m_matrix[10] = ( TReal )( 1.0 - 2.0*quat[0]*quat[0] - 2.0*quat[1]*quat[1] );
}
- Vector.h -
class Vector
{
public:
/*
Constructor. (0, 0, 0, 1) */
Vector();
/*
Constructor. 3 TReal values. */
Vector( const TReal *vector );
/*
Destructor. */
~Vector();
/*
Retrieve vector. */
const TReal *getVector() const { return m_vector; }
/*
Transform the vector by a matrix. */
void transform( const Matrix& m );
/*
Transform the vector by a matrix, not including the scaling or transformation
elements (use only top-left 3x3 of matrix). */
void transform3( const Matrix& m );
/*
Set the values of the vector. Takes 3 TReal values. */
void set( const TReal *vector );
/*
Translate by another vector. */
void add( const Vector& v );
/*
Reset to (0, 0, 0, 1). */
void reset();
const TReal operator[]( TInt index ) const { return m_vector[index]; }
public:
//
Vector data
TReal m_vector[4];
};
inline void Vector::reset()
{
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
98
m_vector[0] = m_vector[1] = m_vector[2] = 0;
m_vector[3] = 1;
}
inline void Vector::set( const TReal *values )
{
m_vector[0] = values[0];
m_vector[1] = values[1];
m_vector[2] = values[2];
}
inline void Vector::add( const Vector& v )
{
m_vector[0] += v.m_vector[0];
m_vector[1] += v.m_vector[1];
m_vector[2] += v.m_vector[2];
m_vector[3] += v.m_vector[3];
}
- Vector.cpp -
Vector::Vector()
{
reset();
}
Vector::Vector( const TReal *values )
{
set( values );
m_vector[3] = 1;
}
Vector::~Vector()
{
}
void Vector::transform( const Matrix& m )
{
TReal vector[4];
const TReal *matrix = m.getMatrix();
vector[0] = m_vector[0]*matrix[0]+m_vector[1]*matrix[4]+m_vector[2]*matrix[8]+matrix[12];
vector[1] = m_vector[0]*matrix[1]+m_vector[1]*matrix[5]+m_vector[2]*matrix[9]+matrix[13];
vector[2] =
m_vector[0]*matrix[2]+m_vector[1]*matrix[6]+m_vector[2]*matrix[10]+matrix[14];
vector[3] =
m_vector[0]*matrix[3]+m_vector[1]*matrix[7]+m_vector[2]*matrix[11]+matrix[15];
m_vector[0] = ( TReal )( vector[0] );
m_vector[1] = ( TReal )( vector[1] );
m_vector[2] = ( TReal )( vector[2] );
m_vector[3] = ( TReal )( vector[3] );
}
void Vector::transform3( const Matrix& m )
{
TReal vector[3];
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
99
const TReal *matrix = m.getMatrix();
vector[0] = m_vector[0]*matrix[0]+m_vector[1]*matrix[4]+m_vector[2]*matrix[8];
vector[1] = m_vector[0]*matrix[1]+m_vector[1]*matrix[5]+m_vector[2]*matrix[9];
vector[2] = m_vector[0]*matrix[2]+m_vector[1]*matrix[6]+m_vector[2]*matrix[10];
m_vector[0] = ( TReal )( vector[0] );
m_vector[1] = ( TReal )( vector[1] );
m_vector[2] = ( TReal )( vector[2] );
m_vector[3] = 1;
}
- Quaternion.h -
#ifndef PI
#
define PI
#endif
3.1415926535897932384626433832795
#ifndef PI_ON_180
#
define PI_ON_180
#endif
(PI/180.0)
class Quaternion
{
public:
/*
Constructor. Retrieves values from angles. */
Quaternion( const TReal *angles ) { fromAngles( angles ); }
/*
Cosntructor. Retrieves values from an interpolation between two other
quaternions. */
Quaternion( const Quaternion& q1, Quaternion& q2, TReal interp ) { slerp( q1, q2,
interp ); }
/*
Set values from angles.
angles (x,y,z) Euler rotation angles.
*/
void fromAngles( const TReal *angles );
/*
Set values from an interpolation between two other quaternions.
This will also modify the second quaternion if it is backwards.
q1, q2 The quaternions to interpolate between
interp A value from 0.0-1.0 indicating the linear interpolation
parameter.
*/
void slerp( const Quaternion& q1, Quaternion& q2, TReal interp );
/*
Get a value from the quaternion. */
TReal operator[]( TInt index ) const { return m_quat[index]; }
/*
Set the inverse of the quaternion. */
void inverse();
private:
//
Quaternion data
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
100
TReal m_quat[4];
};
inline void Quaternion::inverse()
{
m_quat[0] = -m_quat[0];
m_quat[1] = -m_quat[1];
m_quat[2] = -m_quat[2];
m_quat[3] = -m_quat[3];
}
- Quaternion.cpp -
void Quaternion::fromAngles( const TReal *angles )
{
TReal angle;
TReal sr, sp, sy, cr, cp, cy;
angle = angles[2]*0.5f;
Math::Sin( sy, angle );
Math::Cos( cy, angle );
angle = angles[1]*0.5f;
Math::Sin( sp, angle );
Math::Cos( cp, angle );
angle = angles[0]*0.5f;
Math::Sin( sr, angle );
Math::Cos( cr, angle );
TReal crcp = cr*cp;
TReal srsp = sr*sp;
m_quat[0] = ( TReal )( sr*cp*cy-cr*sp*sy );
m_quat[1] = ( TReal )( cr*sp*cy+sr*cp*sy );
m_quat[2] = ( TReal )( crcp*sy-srsp*cy );
m_quat[3] = ( TReal )( crcp*cy+srsp*sy );
}
void Quaternion::slerp( const Quaternion& q1, Quaternion& q2, TReal interp )
{
// Decide if one of the quaternions is backwards
TInt i;
TReal a = 0, b = 0;
for ( i = 0; i < 4; i++ )
{
a += ( q1[i]-q2[i] )*( q1[i]-q2[i] );
b += ( q1[i]+q2[i] )*( q1[i]+q2[i] );
}
if ( a > b )
q2.inverse();
TReal cosom = q1[0]*q2[0]+q1[1]*q2[1]+q1[2]*q2[2]+q1[3]*q2[3];
TReal sclq1, sclq2;
if (( 1.0+cosom ) > 0.00000001 )
{
if (( 1.0-cosom ) > 0.00000001 )
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
101
{
TReal omega, sinom, t1, t2;
Math::ACos( omega, cosom );
Math::Sin( sinom, omega );
Math::Sin( t1, (( 1.0-interp )*omega) );
Math::Sin( t2, (( interp )*omega) );
sclq1 = t1/sinom;
sclq2 = t2/sinom;
}
else
{
sclq1 = 1.0-interp;
sclq2 = interp;
}
for ( i = 0; i < 4; i++ )
m_quat[i] = ( TReal )( sclq1*q1[i]+sclq2*q2[i] );
}
else
{
m_quat[0] = -q1[1];
m_quat[1] = q1[0];
m_quat[2] = -q1[3];
m_quat[3] = q1[2];
Math::Sin( sclq1, (( 1.0-interp )*0.5*PI ) );
Math::Sin( sclq2, ( interp*0.5*PI ) );
for ( i = 0; i < 3; i++ )
m_quat[i] = ( TReal )( sclq1*q1[i]+sclq2*m_quat[i] );
}
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
102
7.3 Appendice C
All’interno di questa appendice è presentato il codice utilizzato per creare
l’applicazione ‘Pokémòn Virtual Pet’. La parte riprodotta di seguito corrisponde
alla parte di codice, presente all’interno dei file .h e .cpp, necessari per la
gestione dei modelli, del loro caricamento e del rendering, quindi la classe
‘Mesh’ e la classe che si occupa del main loop del gioco e quindi di mostrare le
varie interazioni con l’utente, le statistiche, il menù, cioè la classe ‘Pokemon’.
Viene escluso dall’analisi il codice del file 3DObjects.h, in quanto contenente
solamente il codice dei modelli tridimensionali creati ed utilizzati
nell’applicazione stessa, e dei codici delle strutture matematiche già analizzate
all’interno della Appendice B.
Codice Pokémòn Virtual Pet
- Mesh.h e Mesh.cpp Questo file contiene la classe che gestisce i modelli tridimensionali, le loro
texture e la fase di rendering, che sfrutta le OpenGL ES.
Osserviamo con cura la definizione stessa della classe Mesh:
const TInt GlShift = 16;
const TInt shift = GlShift - KShift;
// CONSTANTS
const TUint KInvalidTextureObject = 0xffffffff;
class Mesh : public CBase
{
public:
Mesh()
{
delete iVertex;
delete iFace;
delete[] iGLVerts;
delete[] iGLNormals;
delete[] iGLTexCoords;
delete[] iGLTris;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
103
m_numJoints = 0;
m_pJoints = NULL;
m_Time = 0;
m_totalTime = 0;
m_looping = true;
skeletoned = false;
restart();
}
~Mesh()
{
delete iVertex;
delete iFace;
delete[] iGLVerts;
delete[] iGLNormals;
delete[] iGLTexCoords;
delete[] iGLTris;
if( iTextureObject != 0xffffffff )
glDeleteTextures( 1, &iTextureObject );
TInt i=0;
for ( i = 0; i < m_numJoints; i++ )
{
delete[] m_pJoints[i].m_pRotationKeyframes;
delete[] m_pJoints[i].m_pTranslationKeyframes;
}
m_numJoints = 0;
if ( m_pJoints != NULL )
{
delete[] m_pJoints;
m_pJoints = NULL;
}
m_Time = 0;
m_totalTime = 0;
m_looping = true;
skeletoned = false;
animation = NULL;
animActive = 0;
}
public:
//
Animation keyframe information
struct Keyframe
{
TInt m_jointIndex;
TInt m_time;
// in milliseconds
TReal m_parameter[3];
};
//
Skeleton bone joint
struct Joint
{
TReal m_localRotation[3];
TReal m_localTranslation[3];
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
104
Matrix m_absolute, m_relative;
TInt m_numRotationKeyframes, m_numTranslationKeyframes;
Keyframe *m_pTranslationKeyframes;
Keyframe *m_pRotationKeyframes;
TInt m_currentTranslationKeyframe, m_currentRotationKeyframe;
Matrix m_final;
TInt m_parent;
};
struct AnimationSet
{
TInt initTime;
TInt endTime;
};
public:
void Load(const TReal* verts, const TInt* faces, const TReal* textures,
const TReal* normals, TInt nv, TInt nf, TInt textureSize = 256 );
void LoadAnimationData( TInt totTime, TInt nJoints, const TReal* jointData, const TReal*
keyframeData, const TInt* vertexJointData );
void Draw( bool shadow = false, TReal blend = 1.0 );
void CreateText( const TDesC8& aStr, TInt textureSize );
void CreateQuad();
void SetPosition( TInt x, TInt y, TInt z );
void Rotate( TInt x, TInt y, TInt z );
void Scale( TInt x, TInt y, TInt z );
void SetTexture( GLuint iTexture)
{
iTextureObject = iTexture;
}
void SetDiffuseMaterial( TReal r, TReal g, TReal b, TReal a )
{
matDiffuse[0] = (GLfloat)r;
matDiffuse[1] = (GLfloat)g;
matDiffuse[2] = (GLfloat)b;
matDiffuse[3] = (GLfloat)a;
}
void SetAmbientMaterial( TReal r, TReal g, TReal b, TReal a )
{
matAmbient[0] = (GLfloat)r;
matAmbient[1] = (GLfloat)g;
matAmbient[2] = (GLfloat)b;
matAmbient[3] = (GLfloat)a;
}
void SetSpecularMaterial( TReal r, TReal g, TReal b, TReal a )
{
matSpecular[0] = (GLfloat)r;
matSpecular[1] = (GLfloat)g;
matSpecular[2] = (GLfloat)b;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
105
matSpecular[3] = (GLfloat)a;
}
void SetEmissionMaterial( TReal r, TReal g, TReal b, TReal a )
{
matEmission[0] = (GLfloat)r;
matEmission[1] = (GLfloat)g;
matEmission[2] = (GLfloat)b;
matEmission[3] = (GLfloat)a;
}
void SetShininess( TInt v )
{
shininess = v;
}
/*
Set the values of a particular keyframe for a particular joint.
jointIndex
The joint to setup the keyframe for
keyframeIndex The maximum number of keyframes
time
The time in milliseconds of the keyframe
parameter
The rotation/translation values for the keyframe
isRotation
Whether it is a rotation or a translation keyframe
*/
void setJointKeyframe( TInt jointIndex, TInt keyframeIndex, TInt time, TReal *parameter, bool
isRotation );
/*
Setup joint matrices. */
void setupJoints();
/*
Set looping factor for animation. */
void setLooping( bool looping ) { m_looping = looping; }
/*
Advance animation by a frame. */
void advanceAnimation();
/*
Restart animation. */
void restart(int n = 0 );
void setAnimationSet(int n = 0 );
TInt position[3];
TInt scale[3];
TInt rotation[3];
TVertex* iVertex;
TFace* iFace;
TInt
num_vertices;
TInt
num_faces;
//
Joint information
TInt m_numJoints;
Joint *m_pJoints;
//
Total animation time
TInt m_totalTime;
//
Is the animation looping?
bool m_looping;
bool visible;
bool skeletoned;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
106
AnimationSet * animation;
int animActive;
bool nothingToDo;
TInt m_Time;
GLuint
GLfixed*
GLfixed*
GLfixed*
TInt
TInt
GLushort*
iTextureObject;
iGLVerts;
iGLNormals;
iGLTexCoords;
iGLTriCount;
iGLVertCount;
iGLTris;
GLfloat matDiffuse[4];
GLfloat matAmbient[4];
GLfloat matSpecular[4];
GLfloat matEmission[4];
TInt shininess;
};
Come si può facilmente notare il costruttore non fa altro che inizializzare tutte
le strutture necessarie e le variabili utilizzate.
All’interno di tale classe sono definite alcune strutture per la creazione e la
fruizione dell’animazione dei modelli, come Keyframe, Joint e AnimationSet.
La prima struttura è adoperata per contenere tutte le informazioni di un singolo
keyframe, ovvero l’indice dell’osso a cui tale keyframe fa riferimento, il suo
tempo e tre parametri che rappresentano la rotazione o la traslazione dell’osso.
La struttura Joint conterrà invece tutte le informazioni di un osso e quindi le
matrici di rototraslazione iniziali e tutti i vari keyframe che ne caratterizzano
l’animazione, oltre al loro numero. Un’altra importante informazione che
contiene questa struttura è l’indice dell’osso che fa da nodo padre nell’albero
che rappresenta lo scheletro.
L’ultima struttura è adibita invece a contenere la lunghezza di una sequenza di
animazione e quindi l’indice del keyframe iniziale e quello finale.
Le variabili presenti all’interno della classe servono sia per il rendering con le
OpenGL ES e per settare i dettagli del modello come texture e materiale, che per
il caricamento di tutte le informazioni necessarie e per l’animazione scheletrica.
Importante è notare la presenza di alcune variabili che indicano se il modello
deve essere renderizzato o meno, se l’animazione deve essere ripetuta o meno e
una molto importante che la rappresentazione dello scorrere nel tempo per
animare il modello.
E’ importante analizzare i metodi all’interno di questa classe per capire come
avviene il caricamento e il rendering della mesh.
Le funzioni Load() e LoadAnimationData() sono due metodi destinati
al’inizializzazione e al caricamento di tutti i dati all’interno di un istanza
specifica della classe e ne determinano quindi il corretto funzionamento.
La prima funzione prende come input diversi array e altri due dati
fondamentali, il numero di vertici e di facce del modelli, che sono in effetti i dati
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
107
creati attraverso le due piccole applicazioni scritte in C, e inizializza tutte le
strutture interne della classe mesh.
void Mesh::Load(const TReal* verts, const TInt* faces, const TReal* textures,
const TReal* normals, TInt nv, TInt nf, TInt textureSize )
{
iVertex = new TVertex[nv];
iFace = new TFace[nf];
num_vertices = nv;
num_faces = nf;
TInt i=0;
TInt v=0, t=0, n=0;
for(i=0; i<nv; i++)
{
iVertex[i] = TVertex( (TInt)verts[v]*100, (TInt)verts[v+1]*100, (TInt)verts[v+2]*100,
(TInt)textures[t], (TInt)textures[t+1],
(TInt)normals[n], (TInt)normals[n+1],
(TInt)normals[n+2] );
v = v+3;
t = t+2;
n = n+3;
}
v=0;
for(i=0; i<nf; i++)
{
iFace[i] = TFace( faces[v], faces[v+1], faces[v+2] );
iFace[i].normalX = iVertex[iFace[i].iV1].normalX +
iVertex[iFace[i].iV2].normalX +
iVertex[iFace[i].iV3].normalX;
iFace[i].normalY = iVertex[iFace[i].iV1].normalY +
iVertex[iFace[i].iV2].normalY +
iVertex[iFace[i].iV3].normalY;
iFace[i].normalZ = iVertex[iFace[i].iV1].normalZ +
iVertex[iFace[i].iV2].normalZ +
iVertex[iFace[i].iV3].normalZ;
v = v+3;
}
delete[] iGLVerts;
delete[] iGLNormals;
delete[] iGLTexCoords;
delete[] iGLTris;
iGLTriCount = nf*3;
iGLVerts=new GLfixed[ iGLTriCount*3 ];
iGLTexCoords=new GLfixed[ iGLTriCount*2 ];
iGLTris=new GLushort[ iGLTriCount ];
iGLNormals=new GLfixed[ iGLTriCount*3 ];
TInt ic=0;
TInt vc=0;
for (i=0;i<nf;i++)
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
108
{
TInt a,b,c;
a=iFace[i].iV1;
b=iFace[i].iV2;
c=iFace[i].iV3;
iGLVerts[vc*3] = iVertex[a].iX << shift;
iGLVerts[vc*3+1] = iVertex[a].iY << shift;
iGLVerts[vc*3+2] = iVertex[a].iZ << shift;
iGLNormals[vc*3] = iVertex[a].normalX << shift;
iGLNormals[vc*3+1] = iVertex[a].normalY << shift;
iGLNormals[vc*3+2] = iVertex[a].normalZ << shift;
iGLTexCoords[vc*2] = ( iVertex[a].iTx << GlShift ) / textureSize;
iGLTexCoords[vc*2+1] = ( iVertex[a].iTy << GlShift ) / textureSize;
iGLTris[ic] = (GLushort)vc;
ic++;
vc++;
iGLVerts[vc*3] = iVertex[b].iX << shift;
iGLVerts[vc*3+1] = iVertex[b].iY << shift;
iGLVerts[vc*3+2] = iVertex[b].iZ << shift;
iGLNormals[vc*3] = iVertex[b].normalX << shift;
iGLNormals[vc*3+1] = iVertex[b].normalY << shift;
iGLNormals[vc*3+2] = iVertex[b].normalZ << shift;
iGLTexCoords[vc*2] = ( iVertex[b].iTx << GlShift ) / textureSize;
iGLTexCoords[vc*2+1] = ( iVertex[b].iTy << GlShift ) / textureSize;
iGLTris[ic] = (GLushort)vc;
ic++;
vc++;
iGLVerts[vc*3] = iVertex[c].iX << shift;
iGLVerts[vc*3+1] = iVertex[c].iY << shift;
iGLVerts[vc*3+2] = iVertex[c].iZ << shift;
iGLNormals[vc*3] = iVertex[c].normalX << shift;
iGLNormals[vc*3+1] = iVertex[c].normalY << shift;
iGLNormals[vc*3+2] = iVertex[c].normalZ << shift;
iGLTexCoords[vc*2] = ( iVertex[c].iTx << GlShift) / textureSize;
iGLTexCoords[vc*2+1] = ( iVertex[c].iTy << GlShift) / textureSize;
iGLTris[ic] = (GLushort)vc;
ic++;
vc++;
}
iTextureObject = KInvalidTextureObject;
int l=0;
for(l=0; l<4; l++)
{
matDiffuse[l] = 1.0;
matAmbient[l] = 1.0;
matSpecular[l] = 1.0;
matEmission[l] = 1.0;
}
shininess = 0;
visible = true;
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
109
Il secondo metodo nuovamente in input prende alcuni array, sempre generati
dai programmi in C, quindi senza alcuno sforzo del programmatore, se non una
semplice operazione di “copia e incolla”, e un parametro che corrisponde alla
durata totale dell’animazione salvata. Vengono quindi con questa funzione
inizializzati i parametri relativi ai keyframes e allo scheletro.
void Mesh::LoadAnimationData( TInt totTime, TInt nJoints, const TReal* jointData, const TReal*
keyframeData, const TInt* vertexJointData )
{
skeletoned = true;
m_totalTime = totTime*1000;
m_numJoints = nJoints;
m_pJoints = new Joint[m_numJoints];
TInt i = 0;
for(i=0; i<num_vertices; i++)
iVertex[i].m_boneID = vertexJointData[i];
TInt j=0;
TInt k=0;
for ( i = 0; i < nJoints; i++ )
{
j++;
m_pJoints[i].m_parent = (TInt)jointData[j];
j++;
m_pJoints[i].m_localTranslation[0] = (TInt)jointData[j] << shift;
j++;
m_pJoints[i].m_localTranslation[1] = (TInt)jointData[j] << shift;
j++;
m_pJoints[i].m_localTranslation[2] = (TInt)jointData[j] << shift;
j++;
m_pJoints[i].m_localRotation[0] = jointData[j];
j++;
m_pJoints[i].m_localRotation[1] = jointData[j];
j++;
m_pJoints[i].m_localRotation[2] = jointData[j];
j++;
k++;
TInt l = 0;
m_pJoints[i].m_numTranslationKeyframes = (TInt)keyframeData[k];
m_pJoints[i].m_pTranslationKeyframes = new
Keyframe[(TInt)keyframeData[k]];
k++;
for ( l = 0; l < m_pJoints[i].m_numTranslationKeyframes; l++ )
{
TInt time = keyframeData[k];
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
110
k++;
TReal m_parameter[3];
m_parameter[0] = (TInt)keyframeData[k] << shift;
k++;
m_parameter[1] = (TInt)keyframeData[k] << shift;
k++;
m_parameter[2] = (TInt)keyframeData[k] << shift;
k++;
setJointKeyframe( i, l, time*1000, m_parameter, false );
}
m_pJoints[i].m_numRotationKeyframes = (TInt)keyframeData[k];
m_pJoints[i].m_pRotationKeyframes = new
Keyframe[(TInt)keyframeData[k]];
k++;
for ( l = 0; l < m_pJoints[i].m_numRotationKeyframes; l++ )
{
TInt time = keyframeData[k];
k++;
TReal m_parameter[3];
m_parameter[0] = keyframeData[k];
k++;
m_parameter[1] = keyframeData[k];
k++;
m_parameter[2] = keyframeData[k];
k++;
setJointKeyframe( i, l, time*1000, m_parameter, true );
}
}
setupJoints();
animActive = 0;
nothingToDo = false;
restart(animActive);
jointData = NULL;
keyframeData = NULL;
vertexJointData = NULL;
}
Quest’ultima funzione fa riferimento ad altri metodi della classe mesh.
Vediamo di capire come questi metodi influenzano la creazione e
l’inizializzazione dell’animazione scheletrica.
Il primo metodo che si incontra leggendo il codice è setJointKeyframe(). Questa
funzione prende in input come parametri il numero del keyframe e quello
dell’osso su cui si vuole operare, il tempo relativo al keyframe, i parametri di
rotazione o traslazione, a seconda che l’ultimo parametro booleano risulti true o
false. Con tutti questi dati è possibile memorizzare quindi i dati necessari
all’animazione di un osso relativa a un dato keyframe.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
111
void Mesh::setJointKeyframe( TInt jointIndex, TInt keyframeIndex, TInt time, TReal *parameter, bool
isRotation )
{
Keyframe& keyframe = isRotation ?
m_pJoints[jointIndex].m_pRotationKeyframes[keyframeIndex] :
m_pJoints[jointIndex].m_pTranslationKeyframes[keyframeIndex];
keyframe.m_jointIndex = jointIndex;
keyframe.m_time = time;
keyframe.m_parameter[0] = parameter[0];
keyframe.m_parameter[1] = parameter[1];
keyframe.m_parameter[2] = parameter[2];
}
Successivamente scorrendo il codice ci si imbatte nel metodo setupJoints(). Tale
funzione permette di inizializzare tutte le matrici di rototraslazione dello
scheletro relative ad ogni osso e al suo nodo predecessore e di posizionare ogni
vertice influenzato dal relativo osso nella giusta posizione e difatti non ha
bisogno di alcun parametro di input.
void Mesh::setupJoints()
{
TInt i=0;
for ( i = 0; i < m_numJoints; i++ )
{
Joint& joint = m_pJoints[i];
joint.m_relative.setRotationRadians( joint.m_localRotation );
joint.m_relative.setTranslation( joint.m_localTranslation );
if ( joint.m_parent >= 0 )
{
joint.m_absolute.set( m_pJoints[joint.m_parent].m_absolute.m_matrix );
joint.m_absolute.postMultiply( joint.m_relative );
}
else
joint.m_absolute.set( joint.m_relative.m_matrix );
}
for ( i = 0; i < num_vertices; i++ )
{
if ( iVertex[i].m_boneID >= 0 )
{
const Matrix& matrix = m_pJoints[iVertex[i].m_boneID].m_absolute;
TReal m_location[3];
m_location[0] = iVertex[i].iX;
m_location[1] = iVertex[i].iY;
m_location[2] = iVertex[i].iZ;
matrix.inverseTranslateVect( m_location );
matrix.inverseRotateVect( m_location );
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
112
iVertex[i].iX = (TInt)m_location[0];
iVertex[i].iY = (TInt)m_location[1];
iVertex[i].iZ = (TInt)m_location[2];
TReal m_vertexNormals[3];
m_vertexNormals[0] = iVertex[i].normalX;
m_vertexNormals[1] = iVertex[i].normalY;
m_vertexNormals[2] = iVertex[i].normalZ;
matrix.inverseRotateVect( m_vertexNormals );
iVertex[i].normalX = (TInt)m_vertexNormals[0];
iVertex[i].normalY = (TInt)m_vertexNormals[1];
iVertex[i].normalZ = (TInt)m_vertexNormals[2];
}
}
}
Il rimanente metodo restart() permette invece di settare il fattore temporale
della particolare istanza della classe mesh a zero e quindi imposta il keyframe
attuale di ogni osso al primo dell’animazione totale e resetta le matrici di
rototraslazione. Quest’ultima operazione potrebbe risultare ripetitiva in questo
caso, ma lo stesso metodo viene utilizzato nel codice qualora con il passare del
tempo si superasse il numero totale di keyframe e quindi si dovesse far ripartire
l’animazione.
void Mesh::restart(int n)
{
for ( TInt i = 0; i < m_numJoints; i++ )
{
m_pJoints[i].m_currentRotationKeyframe =
m_pJoints[i].m_currentTranslationKeyframe = 0;
m_pJoints[i].m_final.set( m_pJoints[i].m_absolute.getMatrix());
}
if(n==0)
m_Time = 0;
else
m_Time = animation[n].initTime*1000;
nothingToDo = false;
}
E’ interessante però capire come progredisce l’animazione e quindi bisogna
dare un attento sguardo alla funzione advanceAnimation(). Questo metodo in
pratica fa avanzare il fattore temporale dell’istanza specifica della classe mesh e
determina così attraverso una semplice interpolazione tra il keyframe
antecedente tale fattore e quello successivo.
void Mesh::advanceAnimation()
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
113
{
#ifdef __WINS__
m_Time += 1000;
#else
m_Time += 4000;
#endif
TInt time = m_Time;
if ( time > animation[animActive].endTime*1000 )
{
if ( m_looping )
{
restart(animActive);
time = animation[animActive].initTime*1000;
}
else
{
time = animation[animActive].endTime*1000;
nothingToDo = true;
}
}
for ( TInt i = 0; i < m_numJoints; i++ )
{
TReal transVec[3];
Matrix transform;
TInt frame;
Joint *pJoint = &m_pJoints[i];
if ( pJoint->m_numRotationKeyframes == 0 && pJoint->m_numTranslationKeyframes
== 0 )
{
pJoint->m_final.set( pJoint->m_absolute.getMatrix());
continue;
}
frame = pJoint->m_currentTranslationKeyframe;
while ( frame < pJoint->m_numTranslationKeyframes && pJoint>m_pTranslationKeyframes[frame].m_time < time )
{
frame++;
}
pJoint->m_currentTranslationKeyframe = frame;
if ( frame == 0 ){
transVec[0] = pJoint->m_pTranslationKeyframes[0].m_parameter[0];
transVec[1] = pJoint->m_pTranslationKeyframes[0].m_parameter[1];
transVec[2] = pJoint->m_pTranslationKeyframes[0].m_parameter[2];
}
else if ( frame == pJoint->m_numTranslationKeyframes ){
transVec[0] = pJoint->m_pTranslationKeyframes[frame-1].m_parameter[0];
transVec[1] = pJoint->m_pTranslationKeyframes[frame-1].m_parameter[1];
transVec[2] = pJoint->m_pTranslationKeyframes[frame-1].m_parameter[2];
}
else
{
const Mesh::Keyframe& curFrame = pJoint>m_pTranslationKeyframes[frame];
const Mesh::Keyframe& prevFrame = pJoint>m_pTranslationKeyframes[frame-1];
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
114
TReal timeDelta = curFrame.m_time-prevFrame.m_time;
TReal interpValue = ( TReal )(( time-prevFrame.m_time )/timeDelta );
transVec[0] = (prevFrame.m_parameter[0]+( curFrame.m_parameter[0]prevFrame.m_parameter[0] )*interpValue);
transVec[1] = (prevFrame.m_parameter[1]+( curFrame.m_parameter[1]prevFrame.m_parameter[1] )*interpValue);
transVec[2] = (prevFrame.m_parameter[2]+( curFrame.m_parameter[2]prevFrame.m_parameter[2] )*interpValue);
}
frame = pJoint->m_currentRotationKeyframe;
while ( frame < pJoint->m_numRotationKeyframes && pJoint>m_pRotationKeyframes[frame].m_time < time )
{
frame++;
}
pJoint->m_currentRotationKeyframe = frame;
if ( frame == 0 )
transform.setRotationRadians( pJoint>m_pRotationKeyframes[0].m_parameter );
else if ( frame == pJoint->m_numRotationKeyframes )
transform.setRotationRadians( pJoint->m_pRotationKeyframes[frame1].m_parameter );
else
{
const Mesh::Keyframe& curFrame = pJoint->m_pRotationKeyframes[frame];
const Mesh::Keyframe& prevFrame = pJoint->m_pRotationKeyframes[frame1];
TReal timeDelta = curFrame.m_time-prevFrame.m_time;
TReal interpValue = ( TReal )(( time-prevFrame.m_time )/timeDelta );
TReal rotVec[3];
rotVec[0] = prevFrame.m_parameter[0]+( curFrame.m_parameter[0]prevFrame.m_parameter[0] )*interpValue;
rotVec[1] = prevFrame.m_parameter[1]+( curFrame.m_parameter[1]prevFrame.m_parameter[1] )*interpValue;
rotVec[2] = prevFrame.m_parameter[2]+( curFrame.m_parameter[2]prevFrame.m_parameter[2] )*interpValue;
transform.setRotationRadians( rotVec );
}
transform.setTranslation( transVec );
Matrix relativeFinal( pJoint->m_relative );
relativeFinal.postMultiply( transform );
if ( pJoint->m_parent < 0 )
pJoint->m_final.set( relativeFinal.getMatrix());
else
{
pJoint->m_final.set( m_pJoints[pJoint->m_parent].m_final.getMatrix());
pJoint->m_final.postMultiply( relativeFinal );
}
}
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
115
L’ultimo metodo di rilievo all’interno della classe mesh è quello che si occupa
di aggiornare lo stato dei dati dei vertici, delle facce e delle normali relativi alle
OpenGL ES, sia che la mesh sia animata o meno, ovvero la funzione Draw().
Questa funzione dopo aver compiuto i relativi aggiornamenti, utilizza delle
chiamate a funzioni implementate nelle OpenGL ES ed effettua il rendering
vero e proprio.
void Mesh::Draw( bool shadow, TReal blend )
{
TInt vc=0;
for ( TInt j = 0; j < num_faces; j++ )
{
if ( skeletoned && iVertex[iFace[j].iV1].m_boneID >= 0 )
{
// rotate according to transformation matrix
const Matrix& final = m_pJoints[iVertex[iFace[j].iV1].m_boneID].m_final;
TReal m_vertexNormals[3];
m_vertexNormals[0] = iVertex[iFace[j].iV1].normalX;
m_vertexNormals[1] = iVertex[iFace[j].iV1].normalY;
m_vertexNormals[2] = iVertex[iFace[j].iV1].normalZ;
Vector newNormal( m_vertexNormals );
newNormal.transform3( final );
iGLNormals[vc*3] = (TInt)newNormal.m_vector[0] << shift;
iGLNormals[vc*3+1] = (TInt)newNormal.m_vector[1] << shift;
iGLNormals[vc*3+2] = (TInt)newNormal.m_vector[2] << shift;
TReal m_location[3];
m_location[0] = iVertex[iFace[j].iV1].iX;
m_location[1] = iVertex[iFace[j].iV1].iY;
m_location[2] = iVertex[iFace[j].iV1].iZ;
Vector newVertex( m_location );
newVertex.transform( final );
iGLVerts[vc*3] = (TInt)newVertex.m_vector[0] << shift;
iGLVerts[vc*3+1] = (TInt)newVertex.m_vector[1] << shift;
iGLVerts[vc*3+2] = (TInt)newVertex.m_vector[2] << shift;
}
else
{
iGLVerts[vc*3] = iVertex[iFace[j].iV1].iX << shift;
iGLVerts[vc*3+1] = iVertex[iFace[j].iV1].iY << shift;
iGLVerts[vc*3+2] = iVertex[iFace[j].iV1].iZ << shift;
iGLNormals[vc*3] = iVertex[iFace[j].iV1].normalX << shift;
iGLNormals[vc*3+1] = iVertex[iFace[j].iV1].normalY << shift;
iGLNormals[vc*3+2] = iVertex[iFace[j].iV1].normalZ << shift;
}
vc++;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
116
if ( skeletoned && iVertex[iFace[j].iV2].m_boneID >= 0 )
{
// rotate according to transformation matrix
const Matrix& final = m_pJoints[iVertex[iFace[j].iV2].m_boneID].m_final;
TReal m_vertexNormals[3];
m_vertexNormals[0] = iVertex[iFace[j].iV2].normalX;
m_vertexNormals[1] = iVertex[iFace[j].iV2].normalY;
m_vertexNormals[2] = iVertex[iFace[j].iV2].normalZ;
Vector newNormal( m_vertexNormals );
newNormal.transform3( final );
iGLNormals[vc*3] = (TInt)newNormal.m_vector[0] << shift;
iGLNormals[vc*3+1] = (TInt)newNormal.m_vector[1] << shift;
iGLNormals[vc*3+2] = (TInt)newNormal.m_vector[2] << shift;
TReal m_location[3];
m_location[0] = iVertex[iFace[j].iV2].iX;
m_location[1] = iVertex[iFace[j].iV2].iY;
m_location[2] = iVertex[iFace[j].iV2].iZ;
Vector newVertex( m_location );
newVertex.transform( final );
iGLVerts[vc*3] = (TInt)newVertex.m_vector[0] << shift;
iGLVerts[vc*3+1] = (TInt)newVertex.m_vector[1] << shift;
iGLVerts[vc*3+2] = (TInt)newVertex.m_vector[2] << shift;
}
else
{
iGLVerts[vc*3] = iVertex[iFace[j].iV2].iX << shift;
iGLVerts[vc*3+1] = iVertex[iFace[j].iV2].iY << shift;
iGLVerts[vc*3+2] = iVertex[iFace[j].iV2].iZ << shift;
iGLNormals[vc*3] = iVertex[iFace[j].iV2].normalX << shift;
iGLNormals[vc*3+1] = iVertex[iFace[j].iV2].normalY << shift;
iGLNormals[vc*3+2] = iVertex[iFace[j].iV2].normalZ << shift;
}
vc++;
if ( skeletoned && iVertex[iFace[j].iV3].m_boneID >= 0 )
{
// rotate according to transformation matrix
const Matrix& final = m_pJoints[iVertex[iFace[j].iV3].m_boneID].m_final;
TReal m_vertexNormals[3];
m_vertexNormals[0] = iVertex[iFace[j].iV3].normalX;
m_vertexNormals[1] = iVertex[iFace[j].iV3].normalY;
m_vertexNormals[2] = iVertex[iFace[j].iV3].normalZ;
Vector newNormal( m_vertexNormals );
newNormal.transform3( final );
iGLNormals[vc*3] = (TInt)newNormal.m_vector[0] << shift;
iGLNormals[vc*3+1] = (TInt)newNormal.m_vector[1] << shift;
iGLNormals[vc*3+2] = (TInt)newNormal.m_vector[2] << shift;
TReal m_location[3];
m_location[0] = iVertex[iFace[j].iV3].iX;
m_location[1] = iVertex[iFace[j].iV3].iY;
m_location[2] = iVertex[iFace[j].iV3].iZ;
Vector newVertex( m_location );
newVertex.transform( final );
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
117
iGLVerts[vc*3] = (TInt)newVertex.m_vector[0] << shift;
iGLVerts[vc*3+1] = (TInt)newVertex.m_vector[1] << shift;
iGLVerts[vc*3+2] = (TInt)newVertex.m_vector[2] << shift;
}
else
{
iGLVerts[vc*3] = iVertex[iFace[j].iV3].iX << shift;
iGLVerts[vc*3+1] = iVertex[iFace[j].iV3].iY << shift;
iGLVerts[vc*3+2] = iVertex[iFace[j].iV3].iZ << shift;
iGLNormals[vc*3] = iVertex[iFace[j].iV3].normalX << shift;
iGLNormals[vc*3+1] = iVertex[iFace[j].iV3].normalY << shift;
iGLNormals[vc*3+2] = iVertex[iFace[j].iV3].normalZ << shift;
}
vc++;
}
glMatrixMode(GL_MODELVIEW);
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FIXED, 0, iGLVerts );
glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer( GL_FIXED, 0, iGLNormals );
if( iTextureObject != KInvalidTextureObject )
{
glBindTexture( GL_TEXTURE_2D, iTextureObject );
glEnable( GL_TEXTURE_2D );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FIXED, 0, iGLTexCoords );
}
else
{
glDisable( GL_TEXTURE_2D );
glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
}
glMaterialfv(
glMaterialfv(
glMaterialfv(
glMaterialfv(
glMaterialx(
GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse );
GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient );
GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular );
GL_FRONT_AND_BACK, GL_EMISSION, matEmission );
GL_FRONT_AND_BACK, GL_SHININESS, shininess << 16 );
if(shadow)
glColor4x( 1.0, 1.0, 1.0, blend ); //White
else
glColor4x( 1.0, 1.0, 1.0, blend ); //White
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glDrawElements( GL_TRIANGLES, iGLTriCount, GL_UNSIGNED_SHORT, iGLTris );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY );
}
La classe Mesh, ora analizzata, fa uso di alcune classi e strutture definite in altre
parti del codice: l’analisi di queste viene però riservata ad un lettore interessato
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
118
alla reale implementazione di matrici, vettori e quaternion, tipici elementi della
matematica tridimensionale dei videogiochi moderni nella Appendice B.
- Pokemon.h e Pokemon.cpp Apparirà sicuramente più interessante analizzare la classe che rappresenta la
gestione del gioco vera e propria e quindi i suoi metodi, gli algoritmi di
gestione della crescita del cucciolo, dell’interazione tra i differenti modelli e
dell’avanzamento delle animazioni relative alle diverse pressioni dei tasti del
cellulare.
class CPokemon : public CBase
{
public: // Constructors and destructor
/**
* The factory method for creating a new CPokemon object.
*/
static CPokemon* NewL( TUint, TUint );
/**
* Destructor.
*/
virtual ~CPokemon();
public: // New functions
/**
* Initializes the rendering object.
*/
void AppInit( void );
void setAppTexture( int index, TUint8 *tex );
/// Container updates key events here:
/// @param aKeyEvent key event type
/// @param aType key event code
void KeyEvent( const TKeyEvent& aKeyEvent,TEventCode aType );
/**
* Finalizes the object.
*/
void AppExit( void );
/**
* Renders one frame.
* @param iFrame The number of the frame to be rendered.
*/
void AppCycle( TInt iFrame );
/**
* Sets the shading to flat.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
119
*/
void FlatShading( void );
/**
* Sets the shading to smooth.
*/
void SmoothShading( void );
void CalculateProjectionMatrix( void );
void ShowPresentation();
void ShowMenu();
void PlayGame();
protected: // New functions
/**
* Constructor.
*/
CPokemon( TUint, TUint );
/**
* Second phase contructor.
*/
void ConstructL( void );
private: // Data
// Width of the screen
TUint
iScreenWidth;
// Height of the screen
TUint
iScreenHeight;
public:
Mesh Pikachu;
Mesh Ambient, Ball, Pokeball, Ciotola, Food, Shit;
Mesh Water, Siringa, Grabber;
Mesh Start;
TInt pos, rot, vel;
TReal time, blending;
TInt
cen, sec, min, hour;
TReal infoTime, shadowTime, animTime, baseballTime, soundTime;
TInt
menuItem, istrItem;
TUint8
aKey[ 256 ];
// keyboard status
// List for texture objects
GLuint iTexObjects[NTEX];
GLfloat iShadowMat[16];
bool started, showInfo, showShadow, reset, born, justBorn, badState;
bool wantToSleep, menu, instr, loading, joyPress, morphing, morphed;
bool soundActive, dead, wantSomething, showStat;
TInt pLife, pSleep, pEnjoy, pEat;
TInt lastAction[3];
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
120
TInt action, initTime, endTime;
TInt m_anim, iKey;
CSndMixer*
TSample
TSample
TSample
iSndMixer;
// Sound mixer
iMusic;
// sampled music
pikachuPazzo, pikachuFelice, pikachuRussa, pikachuSalto;
pikachuEvolution, pikachuMalato;
// AppUi class pointer
CPokemonAppUi* iAppUi;
};
Osservando il codice della classe Pokemon si possono notare il numero di
modelli utilizzati all’interno dell’applicazione e quindi si può già immaginare la
consistenza del rendering. Molte sono le variabili booleane utilizzate per
sincronizzare eventi o per stabilire il cambiamento di stato o meno del cucciolo
in un particolare momento. Evidenti appaiono anche le variabili che tengono
conto del momentaneo valore della salute, del riposo, del divertimento e della
sazietà e un array che contiene informazioni sulle ultime azioni compiute dal
cucciolo o quelle ordinategli.
Immediatamente sotto appaiono alcuni riferimenti al mixer audio e alcuni
frammenti di audio utilizzati all’interno del gioco.
L’inizializzazione dell’applicazione per quanto riguarda le OpenGL ES viene
effettuata nel metodo AppInit() in cui vengono quindi create e inizializzate il
Viewport e la matrice di proiezione e i piani di clipping, le luci ambientali e una
semplice luce di scena atta a illuminare il cucciolo e la scena e alcune altre
impostazioni di base.
void CPokemon::AppInit( void )
{
// Set the screen background color.
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
/* Make OpenGL ES automatically normalize all normals after tranformations.
This is important when making irregular xforms like scaling, or if we
have specified nonunit-length normals. */
glEnable( GL_NORMALIZE );
// Initialize viewport and projection.
glViewport( 0, 0, iScreenWidth, iScreenHeight );
glMatrixMode( GL_PROJECTION );
glFrustumf( -1.f, 1.f, -1.f, 1.f, 3.f, 1000.f );
glMatrixMode( GL_MODELVIEW );
// Set up global ambient light.
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, globalAmbient );
// Set up lamp.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
121
glEnable(
glLightfv(
glLightfv(
glLightfv(
glLightfv(
GL_LIGHT0 );
GL_LIGHT0, GL_DIFFUSE, lightDiffuseLamp );
GL_LIGHT0, GL_AMBIENT, lightAmbientLamp );
GL_LIGHT0, GL_SPECULAR, lightDiffuseLamp );
GL_LIGHT0, GL_POSITION, lightPositionLamp );
// Set shading mode
glShadeModel( GL_SMOOTH );
Start.CreateQuad();
/* Textures are initialized in OpenGL ES API by this
function. Use glDeleteTextures() in destructor. */
if(NTEX>0)
glGenTextures( NTEX, iTexObjects );
// Do not use perspective correction
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
}
Una volta inizializzata l’applicazione, il processo viene eseguito seguendo un
main loop predefinito che corrisponde a quello eseguito nel metodo
AppCycle():
void CPokemon::AppCycle( TInt iFrame )
{
time++;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
if(!started && !menu )
{
ShowPresentation();
}//end of presentation
else if(!menu && started)
{
PlayGame();
} //end of game drawing
else if(menu)
{
ShowMenu();
//menu drawing
}
}
Si può notare che l’implementazione di questo ciclo corrisponde quasi ad uno
standard, ovvero si riproduce una sorta di presentazione, in cui avviene il
caricamento di alcuni file necessari e si mostrano delle immagini del produttore
dell’applicazione o dell’applicazione stessa, poi si passa al menù in cui si
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
122
presentano diverse opzioni e si può anche scegliere di far partire il gioco e
quindi si mostra il gioco vero e proprio.
Analizziamo qui di seguito alcune parti dei metodi presentati nella funzione
precedente per non appesantire troppo la digressione. Il lettore interessato può
comunque trovare il codice completo nella Appendice C.
Il primo metodo ShowPresentation(), come già enunciato, ha il compito di
mostrare alcune schermate di attesa e di presentazione. Viene fatta partire la
musica di sottofondo e quindi mostrata prima un’immagine con il logo del
produttore e successivamente una schermata che attende che l’utente sia pronto
per utilizzare l’applicazione e quindi mostrargli il menu.
void CPokemon::ShowPresentation()
{
[...]
if(time<2)
{
// play music on channel 0 at 16KHz with volume 256 (max)
iSndMixer->Play( iMusic, 2, 16000, 20 );
iSndMixer->Resume();
}
else if(time<25)
{
Start.SetTexture( iTexObjects[3] );
[...]
Start.Draw();
}
else
{
Start.SetTexture( iTexObjects[2] );
[...]
Start.Draw();
if( joyPress )
{
[...]
menu = true;
}
}
}
Il metodo ShowMenu() risulta più complesso in quanto le scelte possibili sono
diverse e perché la differenza di ciò che viene mostrato non è più data solo
dallo scorrere del tempo, ma dall’interazione con l’utente e quindi dalle
decisioni che questo compie.
void CPokemon::ShowMenu()
{
[...]
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
123
if ( aKey[ '9' ] && (time-soundTime>5)) //cambia lo stato del suono
{
soundTime = time;
soundActive = !soundActive;
if(soundActive)
iSndMixer->Pause();
else
iSndMixer->Resume();
}
[...]
Start.Draw();
//gestione dell’interazione delle frecce premute dall’utente all’interno del menu
if(aKey[ EStdKeyDownArrow ] && !instr && (time-infoTime>5) && !loading)
{
infoTime = time;
menuItem++;
if(menuItem>2)
menuItem = 0;
}
else if(aKey[ EStdKeyUpArrow ] && !instr && (time-infoTime>5) && !loading)
{
infoTime = time;
menuItem--;
if(menuItem<0)
menuItem = 2;
}
//------------------------ LOADING --------------------------//
if(loading)
{
[...]
//viene effettuato il caricamento dei modelli
//--------------------LOADING DATA -----------------------//
[...]
//vengono eventualmente caricati i valori delle caratteristiche
salvate in chiusura della precedente partita
//se è la prima volt ache si gioca bisogna mostrare la nascita del cucciolo dalla sfera Pokè
if((pLife==100)&&(pEat==0)&&(pSleep==0)&&(pEnjoy==0) && !morphed)
justBorn = true;
//altrimenti si posiziona il Pokémòn nella giusta posizione
if(!justBorn)
{
if(Pikachu.position[0] != 0)
Pikachu.position[0] = 0;
if(Pikachu.position[1] != -62)
Pikachu.position[1] = -62;
if(Pikachu.position[2] != 43)
Pikachu.position[2] = 43;
born = true;
Pokeball.position[0]=100;
Pokeball.visible = false;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
124
}
//se il cucciolo si è già evoluto bisogna caricare un modello diverso con materiali diversi
if(morphed)
{
[...]
}
//----------------END OF LOADING DATA --------------------//
started = true;
menu = false;
loading = false;
animTime = time;
}
//-------------------------- MENU ---------------------------//
[...]
//si effettua la scelta su cosa mostrare sullo schermo a seconda delle azioni
dell’utente
//---------------------- INSTRUCTIONS -----------------------//
if(menuItem==1 && ( joyPress ) && (time-infoTime>5))
{
joyPress = false;
infoTime = time;
instr = true;
}
//si effettua la scelta su cosa mostrare sullo schermo a seconda delle azioni dell’utente se
all’interno delle istruzioni
if(instr)
{
if((aKey[ EStdKeyDownArrow ] || aKey[
EStdKeyRightArrow ]) && (time-infoTime>5))
{
infoTime = time;
istrItem++;
if(istrItem>3)
istrItem = -1;
}
else if((aKey[ EStdKeyUpArrow ] || aKey[
EStdKeyLeftArrow ]) && (time-infoTime>5))
{
infoTime = time;
istrItem--;
if(istrItem<0)
istrItem = 0;
}
if(istrItem==-1){
instr = false;
istrItem = 0;
}
}
//-------------------------- EXIT ---------------------------//
if(menuItem==2 && ( joyPress ) && (time-infoTime>5))
{
joyPress = false;
infoTime = time;
iAppUi->HandleCommandL( EEikCmdExit );
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
125
}
//-------------------------- START --------------------------//
if(menuItem==0 && ( joyPress ) && (time-infoTime>5))
{
[...]
//si fa partire il loading e successivamente il gioco
}
}
L’ultimo metodo PlayGame() è quello che contiene poi il vero ciclo di gioco, in
cui si decide cosa far fare al cucciolo in base all’interazione dell’utente o cosa
questo deve fare se l’utente se ne disinteressa, o come decidere se tornare al
menu o visualizzare le statistiche.
void CPokemon::PlayGame()
{
[...]
if( aKey[ '0' ] && ((time-infoTime)>5))
{
infoTime = time;
showInfo = true;
}
if( showInfo )
{
menu = true;
started = true;
// Set the screen background color.
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
}
else if(showStat)
{
if ( aKey[ '5' ] && (time-animTime > 5) ) // showStat
{
animTime = time;
showStat = false;
}
}
else
{
[...]
//rendering dei modelli statici
[...]
if(((time-animTime)>5))
{
//determinazione delle azioni in base ai tasti premuti
}
if ( aKey[ '9' ] && (time-soundTime>5)) //cambia lo stato del suono
{
soundTime = time;
soundActive = !soundActive;
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
126
if(soundActive)
iSndMixer->Pause();
else
iSndMixer->Resume();
}
[...]
effettuare in base alle successioni di eventi
//determinazione delle sequenze di animazione da
[...]
//decremento dei valori se il cucciolo viene lasciato in stato di
abbandono e determinazione azioni casuali del cucciolo
[...]
//Draw Objects
if(morphing && !morphed)
{
//effettuamento del morphing del cucciolo
}
[...]
//rendering del cucciolo stesso
}//end Pikachu drawing
else if(dead)
{
[...]
//animazione della morte del cucciolo
}
//=========================== GUI DRAWING
==============================//
[...]
//rendering dell’interfaccia della parte alta dello schermo
//======================= END OF GUI DRAWING
============================//
}//end of not info drawing
}
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
127
Bibliografia e Sitografia
1. Series60 phone benchmark,
http://www.newlc.com/article.php3?id_article=619,
Articolo che descrive i test effettuati su differenti smartphone ‘Series60’
2. Connection is the Name of the Game,
http://www.animefringe.com/magazine/2004/10/feature/04.php,
Pagina esplicativa sul funzionamento del Tamagotchi Connection
3. Future of Virtual Pet Industry,
http://virtualpet.com/vp/future/future.htm,
Serie di articoli sul futuro dell’industria dedicate ai cuccioli virtuali
4. Tamagotchi Connection Instruction,
http://www.tamagotchiconnection.ca/TAMA_Instructions.pdf,
Foglio di istruzioni del Tamagotchi Connection
5. Tamagotchi Connection,
http://www.tamagotchi.com/products/,
Pagina ufficiale del Tamagotchi Connection
6. Virtual Pet Home Page,
http://www.virtualpet.com/vp/vpindex2.htm,
sito dedicato alla storia e ai dispositivi dedicati ai cuccioli virtuali
7. Speciale: La storia delle console portatili – Anni ’80,
http://www.spaziogames.it/content2/speciali/speciale.asp?id=4596&z
ona=,
Dossier dedicato alla storia delle console portatili
8. WirelessGaming,
http://www.wirelessgaming.it/?view=list_speciali.php,
Sito dedicato al mondo del moblie gaming
9. Game Programmino Italia,
http://gpad.gameprog.it/index.php,
Sito web dedicato alla programmazione di videogiochi
10. News/Vendite da record per videogiochi,
http://www.highscore.it/p.asp?i=51337,
News del sito HighScore.it sul boom delle vendite di videogame nel 2004
11. Editoriale Desse,
http://www.e-duesse.it/,
Sito web pieno di notizie dedicate al mondo informatico e alle tecnologie
12. Forum Nokia,
http://www.forum.nokia.com/main.html,
Sito web dedicato agli sviluppatori di applicazioni per cellulari Nokia
13. Nokia SDK for Series60,
http://www.forum.nokia.com/main.html,
Software Development Kit di Nokia per telefoni della Series60
14. OpenGL ES 3D Example v1.0,
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
128
http://sw.nokia.com/id/9a5a59d0-82c7-4184-b3837ccc853506e8/Series_60_DP_2nd_Ed_FP_2_OpenGL_ES_3D_Example_v
1_0_en.zip,
Esempio e documentazione per le OpenGL ES su SymbianOS
15. Introduction to 3D Graphics in Cpp,
http://sw.nokia.com/id/d7e68ab8-f1ee-428d-ab605c75e77e4118/Series_60_DP_Introduction_To_3D_Graphics_In_Cpp_v1_
1.zip,
Introduzione all’utilizzo di grafica 3D su sistemi SymbianOS in C++
16. SoundMixer Example,
http://sw.nokia.com/id/70a2bde5-9b14-41b3-89ae198b0d8d380d/SoundMixer_Example_v1_0.zip,
Esempio sull’utilizzo di suoni su SymbianOS in C++
17. Hybrid Graphics Ltd.,
http://www.hybrid.fi/,
Sito ufficiale della casa Hybrid Graphics Ltd.
18. OpenGL ES Technical disussion forum,
http://forum.hybrid.fi/viewforum.php?f=3&sid=768c3ea733a33710a3b8
af3e163ea982,
Forum dedicato alle OpenGL ES
19. Non commercial version of Hybrid rasteroid,
http://www.hybrid.fi/main/extra/noncom_es_info.php,
Pagina di download dell’implementazione non commerciale delle
OpenGL ES fornita da Hybrid Graphics Ltd.
20. Khronos.org,
http://www.khronos.org/opengles/tutorials_code/,
Sito ufficiale delle specifiche delle OpenGL ES
21. Zombie character fx bones setup,
http://www.psionic.pwp.blueyonder.co.uk/tutorials/lowpoly/zbones.
html,
Istruzioni per la creazione di animazioni con MilkShape3D
22. Skeletal Animation Tutorial,
http://rsn.gamedev.net/tutorials/ms3danim.asp,
Tutorial sulla creazione di classi e l’implementazione di animazione
scheletrica sfruttando file prodotti da MilkShape3D
23. Blending and Bitmapped fonts,
http://www.typhoonlabs.com/tutorials/Tutorial5.pdf,
Tutorial dedicato all’utilizzo di texture font nelle OpenGL ES
24. GameDev.net Discussion Forum – Consoles, PDAs and Cell Phones,
http://www.gamedev.net/community/forums/forum.asp?forum_id=3
9,
Forum dedicato allo sviluppo di videogiochi su dispositivi mobile
25. NewLC Tutorials,
http://www.newlc.com/rubrique.php3?id_rubrique=3,
Serie di tutorial dedicati ai programmatori su sistemi SymbianOS
26. Symbian: Developer: home,
http://www.symbian.com/developer/index.html,
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
129
Sito web ufficiale del sistema operativo SymbianOS
27. Series60 Platform – Developers,
http://www.series60.com/developers,
Sito ufficiale della piattaforma Series60
28. Series60 Documentation,
http://www.series60.com/developers?pbId=20&pbType=7&c_id=2,
Documentazione ufficiale dedicata ai programmatori su piattaforma
Series60
29. Nokia – Connecting People,
http://www.nokia.it/,
Sito ufficiale della casa finlandese, Nokia
30. Mobile Game Developers,
http://www.mobilegd.com/index.php,
Sito dedicato agli sviluppatori di videogiochi su telefoni cellulari
31. Apron Tutorials,
http://www.morrowland.com/apron/tut_gl.php,
Sito web ricco di tutorial sull’uso delle OpenGL
32. Pokemon Pokédex,
http://www.pokemon.com/Pokedex/flash.asp,
Sito ufficiale dei Pokémòn, con l’elenco completo dei Pokémòn esistenti
33. Vis Ingenii Development,
http://www.vis-ingenii.com/index2.htm,
Pagina ricca di tutorial sull’utilizzo di Alias Maya
34. Alias,
http://www.alias.com/eng/index.shtml,
Sito web ufficiale di Alias Maya e degli altri prodotti della casa
americana
35. MilkShape3D Official Home Page,
http://www.swissquake.ch/chumbalum-soft/,
Pagina web ufficiale del programma MilkShape3D
36. Image*After,
http://www.imageafter.com/textures.php,
Sito utilizzato per alcune textures
37. Nintendogs,
http://www.nintendogs.com/,
Sito ufficiale del gioco dedicato al Nintendo DS.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
130
Terminologia
Algoritmo: si intende un metodo per
la soluzione di un problema adatto a essere
implementato sotto forma di programma.
API: l'acronimo di Application
Program(ming) Interface, indica ogni insieme
di procedure disponibili al programmatore,
di solito raggruppate a formare un set di
strumenti specifici per un determinato
compito.
Applicazione: sono i programmi per
computer che permettono all'utente di
svolgere un lavoro o un'azione, come
scrivere una lettera o ascoltare un brano
musicale. Si differenziano dai software di
sistema, che servono per gestire il
computer.
ASCII: è l'acronimo di American
Standard Code for Information Interchange
(ovvero Codice Standard Americano per lo
Scambio di Informazioni). È un sistema di
codifica dei caratteri a 7 bit comunemente
utilizzato nei calcolatori.
Benchmark: è un test eseguito da un
apposito software che può servire a
misurare la velocità di un computer in
diversi ambiti di lavoro. Esistono software
di benchmark appositamente studiati per
misurare la velocità di un computer
nell'eseguire calcoli di natura grafica, o altri
che privilegiano la capacità nell'eseguire
calcoli di natura gestionale.
Bluetooth: è un termine che identifica
l'aderenza di un prodotto a uno standard
industriale per un PAN sviluppato da
Ericsson e in seguito formalizzato dalla
Bluetooth Special Interest Group (SIG). Lo
standard Bluetooth nasce con l'obiettivo di
unificare le varie tecnologie di connessione
dei terminali mobili, dai computer ai
microfoni passando per i telefoni cellulari e
tutti i dispositivi che si possono
interfacciare a un computer.
Buffer: è un'area particolare della
memoria la cui informazione rimane in
attesa di essere smistata verso un
dispositivo o l'applicativo che deve
elaborarla.
C, C++: In informatica, il C e il C++
sono linguaggi di programmazione.
CAD: acronimo di Computer-Aided
Design, che indica la progettazione grafica
o il disegno tecnico assistito dal computer.
Chip:
Nella
sua
accezione
tecnologica, è anche un acronimo per
l'inglese Consolidated Highly Integrated
Processor (CHIP) ovvero processore
consolidato altamente integrato.
Classe: il termine classe può indicare,
a seconda del contesto, una categoria di
oggetti, un tipo di dati, o la
implementazione di un tipo di dati.
Codice sorgente: spesso abbreviato
sorgente, è un insieme di istruzioni e dati,
utilizzati per implementare un algoritmo in
codice macchina, ossia per costruire un
programma eseguibile per computer.
Console: la console è una piccola
piattaforma dedicata, solitamente realizzata
come dispositivo per i videogiochi e per
l'intrattenimento in generale.
Compilatore: è un programma
traduttore, impiegato per produrre codice
oggetto (in linguaggio macchina) a partire
da codice sorgente scritto in un dato
linguaggio di programmazione di livello
più alto.
Debug: Debugging (o semplicemente
debug) è un'attività che consiste nella
individuazione della porzione di software
affetta da errore (in inglese bug, in italiano
tradotto con baco) rilevati nei software a
seguito dell'utilizzo del programma.
Directory: una directory (chiamata
anche cartella, folder o direttorio), è
un’entità nel file system che contiene un
gruppo di file e altre directory.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
131
Emulatore: nel senso più generale
possibile duplica le funzioni di un
determinato sistema su un secondo sistema
differente dal primo.
File: termine inglese per archivio, è
un insieme di informazioni codificate
organizzate come una sequenza (di byte),
immagazzinate come un singolo elemento
su una memoria di massa, all'interno del
File System esistente su quella particolare
memoria di massa.
File eseguibile: un file eseguibile, o
semplicemente un eseguibile, è un file che
contiene un programma per un computer.
Floating point: Il termine virgola
mobile (in inglese floating point) indica il
metodo di rappresentazione dei numeri
razionali (e di approssimazione dei numeri
reali) e di elaborazione dei dati usati dai
processori
per
compiere
operazioni
matematiche. Si contrappone all'aritmetica
intera o in virgola fissa.
Forum: è un particolare strumento di
comunicazione telematico in cui l'utente
può scrivere dei messaggi (post) che
verranno pubblicati in uno spazio comune
insieme ai messaggi degli altri utenti. Ad
ogni messaggio potranno seguire diverse
risposte
(reply),
che
seguiranno
l'argomento del messaggio originario
(topic).
Game Developers: chi si occupa di
sviluppare un videogioco, all’interno di una
software house.
GUI: L'interfaccia grafica (in inglese
graphical user interface, abbreviato GUI) è
un paradigma di sviluppo che mira a
consentire all'utente di interagire col
calcolatore manipolando graficamente degli
oggetti, svincolandolo dall'obbligo di
imparare una serie di comandi da impartire
con la tastiera come invece avviene con le
interfacce testuali command line interface
(CLI). È lo strato di un'applicazione
software che si occupa del dialogo con
l'utente del sistema utilizzando un
ambiente grafico.
Icona: è un'immagine (di solito un
disegno stilizzato) di dimensioni ridotte il
cui scopo è rappresentare un programma,
un'azione o un tipo di file o, più in
generale, per trasmettere informazione in
forma estremamente sintetica.
IDE: Un integrated development
environment (IDE), in italiano ambiente
integrato di sviluppo, è un software che
aiuta i programmatori nello sviluppo del
software.
Istanza: Un'istanza è un particolare
oggetto di una particolare classe.
Implementazione: indica il modo in
cui un dato prodotto o servizio software,
opportunamente
specificato,
viene
concretamente realizzato.
Interfaccia: L'interfaccia è l'aspetto
che assume ad esempio un software per far
si che l'utente riesca a comunicare e
interagire con la macchina.
Intero: abbreviato con int, indica ogni
tipo di dato che possa rappresentare un
sottoinsieme dell'insieme matematico dei
numeri interi.
JPEG:
l'acronimo
di
Joint
Photographic Experts Group, un comitato
ISO/CCITT che ha definito il primo
standard internazionale di compressione
per immagini a tono continuo, sia a livelli
di grigio che a colori.
Libreria: collezione di modelli di
oggetti da utilizzare in un progetto o
insieme di funzioni di uso comune,
predisposte per essere collegate ad un
programma software.
Linguaggio di programmazione: è un
linguaggio formale dotato di una sintassi
ben definita, e generalmente descritta con
strumenti quali la notazione BNF. Un
linguaggio di programmazione viene
utilizzato per scrivere programmi che
realizzano algoritmi.
Maya: è un pacchetto software di alto
livello, distribuito da Alias, usato nei film e
nell’industria
cinematografica
e
nei
videogames, da poco acquisita da
Autodesk.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
131
Mhz: L'hertz (simbolo Hz) è l'unità di
misura del Sistema Internazionale della
frequenza, usata anche per misurare la
velocità di clock dei processori.
Mobile: accezione inglese per indicare
dispositivi portatili, non legati tramite cavi
di alcun genere.
Multiplayer: è un termine utilizzato
nel mondo dei videogiochi per indicare la
modalità di gioco in cui più persone
possono giocare allo stesso gioco nello
stesso momento.
OpenGL: da Open Graphics Library,
ossia libreria aperta di grafica, è una
specifica che definisce una API per più
linguaggi e per più piattaforme per scrivere
applicazioni che producono computer
grafica 2D e 3D. L'interfaccia consiste in
circa 250 diverse chiamate di funzione che
si possono usare per disegnare complesse
scene tridimensionali a partire da semplici
primitive.
Online: è una parola inglese che
significa letteralmente sulla linea ma viene
quasi sempre utilizzata per indicare le cose
che si trovano su Internet.
Ottimizzazione: è la branca della
matematica applicata che studia teoria e
metodi per la ricerca dei punti di massimo
o minimo di un modello matematico che
traduce in termini matematici un dato
problema
(non
occupandosi
quindi
direttamante di come tali modelli siano stati
costruiti).
Pipeline: si riferisce a un manufatto
composto da più elementi. La pipeline
grafica è una pipeline designata alla
trasformazione dei modelli tridimensionali
del
mondo
in
immagini
bitmap
bidimensionali.
Pixel: abbreviazione inglese di
picture element, è uno dei molti minuscoli
puntini
che
compongono
la
rappresentazione di un'immagine nella
memoria di un computer.
PlugIn: o plug-in, è un programma
non autonomo che interagisce con un altro
programma per ampliarne le funzioni
Pokémòn: abbreviazione di Pocket
Monster, è un linea di videogiochi di
origine giapponese creata da Satoshi Tajiri e
pubblicata dalla Nintendo, incentrati su
tanti vivaci mostriciattoli e sulla possibilità
di allevarli, farli combattere e renderli
sempre piu forti. Molti di questi
mostriciattoli possono evolversi, cioè
cambiare forma e aspetto, acquisendo
caratteristiche nuove e sempre più potenti.
Programma: è la descrizione di un
algoritmo in un linguaggio adatto a essere
eseguito da un computer o da una
macchina virtuale.
Prompt dei comandi: Interfaccia a
linea di comando (dall'inglese Command
Line Interface, in acronimo CLI) è un
termine generico per descrivere un
programma che permette all'utente di
interagire scrivendo righe di comando su
un terminale testuale.
RAM:
acronimo
usato
nell'informatica per Random Access
Memory, è il supporto di memoria su cui è
possibile leggere e scrivere informazioni
con un accesso "casuale", ovvero senza
dover rispettare un determinato ordine
sequenziale, come ad esempio avviene per
un nastro magnetico.
Rendering: il processo di generazione
di un' immagine a partire da una
descrizione degli oggetti tridimensionali
per mezzo di un programma per computer.
Retrocompatibilità: un software nella
versione x è detto retrocompatibile se ogni
applicazione funzionante con la versione x1 funziona anche con la versione x
ROM: acronimo di Read Only
Memory, è una memoria di sola lettura.
Sistemi Embedded: sono dei sistemi
particolari, che sono completamente
incapsulati nel device che controllano
SDK:
acronimo
di
Software
Development Kit, è tipicamente un set di
strumenti di sviluppo che permettono di
creare applicazioni per specifici software,
piattaforme o sistemi operativi.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
132
Series60: denominazione data da
alcuni produttori di telefoni cellulari per
indicare una particolare piattaforma basata
su sistema operativo SymbianOS.
Smartphone:
è
un
dispositivo
portatile che abbina funzionalità di gestione
di dati personali e di telefono.
Software house: aziende informatiche
o spesso case sviluppatrici di videogames.
Sistema Operativo: è il programma
responsabile del diretto controllo e gestione
dell'hardware che costituisce un computer e
delle operazioni di base.
Telefono cellulare: popolarmente
conosciuto come
telefonino, è
un
apparecchio per la comunicazione in
radiotelefonia, collegato alla rete telefonica
di terra tramite centrali di smistamento,
ciascuna capace di diverse connessioni con
gli apparecchi mobili.
Texel: è un pixel di una texture.
Texture: è un’immagine utilizzata per
applicare un disegno sulla superficie di un
modello
tridimensionale
creato
al
computer.
Tool: è un programma o una
applicazione che gli sviluppatori di
software utilizzano per creare, debuggara o
modificare altri programmi e applicazioni.
Variabile: è una locazione di
memoria destinata a contenere dei dati, che
possono essere modificati nel corso
dell'esecuzione del programma. Una
variabile è spesso, ma non sempre,
caratterizzata da un nome.
Wireless:
il
termine
wireless
(dall'inglese senza fili) indica i sistemi di
interconnessione tra dispositivi (computer,
palmari, mouse, tastiere, stampanti, modem
ecc.) che non fanno uso di cavi.
World Wide Web: è una rete di
risorse
di
informazioni,
basata
sull'infrastruttura di Internet. Il Web si basa
su meccanismi per rendere queste risorse
prontamente disponibili al più vasto
insieme possibile di utenti.
Analisi, progettazione e sviluppo di un videogioco tridimensionale del tipo “Virtual Pet” per dispositivi di telefonia mobile
133
Ringraziamenti
Un particolare ringraziamento al professor Francesco Gardin, che mi ha seguito nel
corso dello stage e nella stesura dell’elaborato finale, e mi ha insegnato molte cose sia
durante il suo corso di Realtà Virtuale che nei sei mesi di lavoro, e al professor Mauri
per avermi seguito a distanza.
Grazie! Ai miei genitori: per avermi seguito in questi lunghi anni e per avermi fatto
diventare quello che sono oggi. Per questo vi sarò per sempre grati.
Grazie! A mia sorella: perché seppur distante è sempre vicina.
Grazie! A Ilaria, la mia ragazza: per essermi sempre vicina, in ogni momento, per
rallegrarmi quando nei momenti di tristezza, per essere quello che è e che per me
rappresenta e per essere stata una preziosa consulenza sia matematica che cartoon.
Grazie! A Taglia: perché ha sempre cercato di distogliermi dal mio lavoro, rendendolo
più facile e piacevole, per avermi dato utili consigli e per essere l’amico di sempre.
Grazie! Ad Andre, Carmine, Chiara e Fabbry. Grazie a loro e alle loro maledette carte (a
ognuno le sue) per avermi fatto passare ‘magici’ momenti ed indimenticabili giornate ed
essere sempre disponibili nel momento del bisogno.
Grazie! A Dave e Sam: perché senza il loro supporto e il loro genio forse non sarei già
qui a scrivere questa pagina.
Grazie! Ad Ale, Beebof, Borto, Capo ed Ele, Gazzo, Luca, Ricky e Laura, Scarpy e tutti i
miei amici: perché mi hanno fatto crescere, divertire e trascorrere fantastici momenti e
perché, insomma, ogni tanto bisogna svagarsi!
Grazie! Ad Enzo e Tata Ele: perché, senza di loro, come ci si fa ad organizzare una
serata o una pizzata tutti insieme?
Grazie! A Maurizio: per avermi fatto crescere ancora di più la passione per il 3D, dal
primo momento che ci siamo parlati, e per la sua preziosa consulenza.
Grazie! A Zio Sandro: perché alla fine è anche merito suo se il computer è la mia grande
passione.
Grazie! A Zia Italia: perché mi ha sempre dimostrato il suo affetto, ricoprendomi di
attenzioni.
Grazie! A Rino, Donatella, Davida, Alessia, Enzo, Diana e Fabio: perché mi sopportano
da quando sono piccolo e perché… il padrino è sempre il padrino!
135
Grazie! A Peppino e Anna: per tutto quello che fanno per me, per gli insegnamenti che
mi danno e per avermi fatto sentire sempre a casa.
Grazie! A Peppe e Amelia, Bruno e Amelia, Marina e Valentina, Michele e Marcella,
Francesco e Federica: perché mi hanno accompagnato, in tutto questo tempo (chi più,
chi meno) nel “cammin di nostra vita”.
Grazie, insomma a tutti i parenti, gli amici e i conoscenti, vicini e lontani, indicati o
dimenticati: per avermi fatto crescere, studiare, vivere, divertire, sorridere e piangere;
perché non basterebbero queste poche pagine per dimostrare il mio affetto e la mia
gratitudine; perché “grazie” è solo una parola che non è neanche lontanamente
somigliante alla bella immagine che ne porto nel cuore.
Grazie!
Mauro Gentile.
136
Scarica

Analisi, progettazione e sviluppo di un videogioco