Corso di Laurea in Informatica
Realizzazione e sviluppo di
un mini-gioco per la riabilitazione
della mano
RELATORE
Prof. Nunzio Alberto BORGHESE
CORRELATORE
Dott. Renato MAINETTI
TESI DI LAUREA DI
Jacopo Essenziale
Matr. 740006
Anno Accademico 2013/2014
i
INDICE
1. INTRODUZIONE
2. RIABILITAZIONE
a. RIABILITAZIONE A CASA: PROGETTTO REWIRE
b. IGER: UN GAME ENGINE PER LA RIABILITAZIONE
3. RIABILITAZIONE DELLA MANO
a. STRUMENTI DIGITALI GIA UTILIZZATI NELLA RIABILITAZIONE DELLA MANO
b. OBIETTIVO DEL PROGETTO REALIZZATO
4. STRUMENTI SOFTWARE UTILIZZATI
5. PANDA 3D
a. FUNZIONAMENTO LOOP DI GIOCO
b. COLLISION DETECTION IN PANDA3D
c. MAPPATURA DI INPUT BIDIMENSIONALE NELLO SPAZIO: CAMERA ORTOGRAFICA
d. MAPPATURA DI INPUT BIDIMENSIONALE NELLO SPAZIO: RAY CASTING
6. LEAP MOTION CONTROLLER
a. PROGRAMMARE IL LEAP API
b. PRIMI TEST
c. INTRODURRE NUOVE GESTURES GRABBING
d. IL LEAP MOTION CONTROLLER E LA RIABILITAZIONE
7. REALIZZAZIONE DEL GIOCO: HOT AIR BALLOON
a. SCELTA DELLARCHITETTURA WEB-BASED
b. IL PROGETTO DA REALIZZARE
c. HTML 5 TAG CANVAS E REALIZZAZIONE DEL LOOP DI GIOCO IN JAVASCRIPT
i. DEFINIRE LA ZONA DI GIOCO ALLINTERNO DELLA PAGINA WEB
ii. INIZIALIZZARE E LANCIARE IL GIOCO
d. HOT AIR BALLOON DISEGNARE SUL CANVAS
e. HOT AIR BALLOON IL PRIMO SFONDO E LA MONGOLFIERA
i. CARICAMENTO ASINCRONO E PRELOADING DELLE SPRITES.
f. HOT AIR BALLOON RILEVARE E VALIDARE LINPUT DELLUTENTE
i. RILEVARE LE GESTURES PINCH IN e PINCH OUT
ii. MISURARE LA DISTANZA DELLE DITA SULLO SCHERMO
iii. VALIDARE LINPUT DELLUTENTE
g. HOT AIR BALLOON STRUTTURA DEL GIOCO E GAMEPLAY
h. HOT AIR BALLOON FASI DI GIOCO
i. HOT AIR BALLOON ANIMAZIONI
j. HOT AIR BALLOON GAMEPLAY: MOVIMENTO DEI NEMICI; MONETE E COLLISION
DETECTION
k. HOT AIR BALLOON FEEDBACK E SUGGERIMENTI ALLUTENTE
l. HOT AIR BALLOON SISTEMA DI AUTO-CALIBRAZIONE
8. REALIZZAZIONE DELLA PIATTAFORMA PER I TERAPISTI
ii
a. REQUISITI E NECESSITA DEI TERAPISTI
b. IL PANNELLO DI CONFIGURAZIONE DEL GIOCO
i. INVIO DELLA CONFIGURAZIONE DAL SERVER AL GIOCO
c. IL PANNELLO DELLE STATISTICHE DEI PAZIENTI
i. INVIO DEI DATI DI SESSIONE DAL GIOCO AL SERVER
d. GESTIONE UTENTI E SICUREZZA
9. CONCLUSIONI
a. RISULTATI OTTENUTI CON HOT AIR BALLOON
b. POSSIBILI SVILUPPI FUTURI
10. BIBLIOGRAFIA
1
1 - INTRODUZIONE
La riabilitazione fisica e cognitiva richiede ai pazienti un lavoro intenso e prolungato nel tempo.
Il lavoro che i pazienti devono affrontare durante il periodo di riabilitazione costituito da esercizi
ripetuti che mirano a sollecitare le funzionalit da recuperare. La figura del terapista, in qualit di
istruttore, motivatore, assistente e osservatore del paziente durante lesecuzione dellesercizio
riabilitativo fondamentale. E particolarmente importante che il paziente esegua gli esercizi in
modo corretto per evitare linsorgere di problemi muscolari o scheletrici o acquisisca movimenti non
corretti, situazione che viene indicata come maladaptation (adattamento dannoso).
Purtroppo, oggigiorno, gli oneri relativi al supporto del personale, delle strutture e delle attrezzature
necessarie a mantenere attivi ed efficienti i reparti di riabilitazione allinterno delle strutture
sanitarie, sono quanto mai ingenti, ci costringe tali strutture a cercare di abbattere i costi,
riducendo al minimo necessario la fornitura di tali servizi, rischiando cos di ridurre la qualit del
servizio offerto.
Una possibile soluzione al problema dei costi, che potrebbe addirittura innalzare il livello di qualit
dei servizi riabilitativi offerti dalle strutture sanitarie, quella di decentralizzare il lavoro sul paziente,
permettendo a questultimo di svolgere gran parte degli esercizi riabilitativi a casa, in modo
autonomo, ma sempre sotto la supervisione dei terapisti.
Questo approccio reso oggi possibile, dallampia diffusione, di nuovi strumenti a basso costo di
interazione uomo-macchina (HID Human Interface Devices), che spesso vengono prodotti e
utilizzati in ambito videoludico.
Abbiamo ad esempio:
- Microsoft Kinect
- Wii Balance Board
- Leap Motion Controller
- Tablet e Smartphone con schermi multi-touch
Questi dispositivi sono in grado di tracciare, con sufficiente precisione, molti dei movimenti nello
spazio, o nel piano che compiono gli utenti che li utilizzano. Tali rilevazioni possono essere utilizzate
in ambito riabilitativo per controllare la postura e i movimenti del paziente mentre svolge i propri
esercizi di riabilitazione a casa, fornendo cos la possibilit ai terapisti di supervisionare a distanza il
paziente, e al paziente di svolgere a casa il proprio lavoro di riabilitazione in completa sicurezza.
Inoltre, essendo i dispositivi sopracitati, spesso nati dallindustria videoludica, possibile mappare
allinterno di videogiochi creati ad hoc, gli esercizi di riabilitazione che ogni singolo paziente deve
svolgere, creando cos degli esercizi-giochi (exer-games), che permettano di introdurre una
componente di intrattenimento e divertimento allinterno dellesercizio, rendendo il lavoro di
riabilitazione quotidiano pi stimolante.
Questo ci che viene svolto oggi nellambito del progetto REWIRE (di cui si parler di seguito), ed
ci che si cercato di fare, in piccolo, per quanto riguarda la riabilitazione della mano nel progetto
descritto nei capitoli successivi.
2
2 - RIABILITAZIONE
giusto, prima di procedere oltre, definire cosa si intende per riabilitazione e medicina fisica o
riabilitativa, poich sar largomento centrale di tutto il lavoro descritto in seguito.
Si tratta di quella branca della medicina volta alla diagnosi, terapia e riabilitazione di quelle disabilit
derivate da malattie invalidanti, che possono compromettere le funzionalit motorie, cognitive o
emozionali del paziente.
La medicina riabilitativa coinvolge una serie di figure professionali tra cui quella del fisioterapista,
che si occupa di valutare la condizione dei singoli pazienti e stabilire un percorso riabilitativo
adatto, costituito, spesso da una serie di esercizi da compiere atti al recupero della funzionalit
compromessa.
La funzione del fisioterapista fondamentale nel processo riabilitativo, esso infatti non si limita a
fornire una serie di esercizi che il paziente pu svolgere in autonomia, ma spesso, deve assisterlo
durante lesecuzione fornendo tempestive correzioni in caso di errore, per impedire il
peggioramento delle condizioni iniziali, e fornendo anche la giusta motivazione, che lo spinga a
persistere nellesercizio e ad affrontare le inevitabili difficolt che affronter durante il suo percorso.
importante tenere ben presente questa triplice funzione del terapista di:
- Ideatore del programma di esercizi adatti al paziente
- Correttore di eventuali errori commessi nellesecuzione dei singoli esercizi
- Motivatore del paziente.
In quanto questi tre elementi sono fondamentali affinch il processo riabilitativo vada a buon fine e
dovranno, pertanto, essere presenti anche nel sistema intelligente che affiancher il paziente
durante la riabilitazione a casa propria, quindi in assenza del terapista.
2.a - RIABILITAZIONE A CASA: PROGETTO REWIRE
REWIRE un progetto sostenuto dallUnione Europea che mira a generare una piattaforma di
riabilitazione multi-livello basata su exer-games (http://www.rewire-project.eu).
Scopo del progetto quello di creare un sistema personalizzato che possa essere distribuito su
grande scala nelle case di tutti i pazienti che abbiano bisogno di affrontare un processo di
riabilitazione per recuperare funzionalit compromesse.
un progetto indirizzato a pazienti, dimessi dalle strutture ospedaliere, che hanno bisogno di
continuare a eseguire esercizi di riabilitazione, sotto la sorveglianza remota dei loro terapisti.
La piattaforma REWIRE costituita principalmente da tre macro-componenti:
- PATIENT STATION (PS): Si tratta di un sistema, inteso come insieme di hardware / software,
che viene installato a casa dei pazienti. Consiste in sostanza di un insieme di mini-videogiochi
che vengono mostrati sullo schermo di un televisore ai pazienti.
Il sistema di input segue il paradigma Hands Free (o a mani libere), si tratta, in breve di
utilizzare una serie di dispositivi (ad esempio il Microsoft Kinect), per il tracciamento della
posizione del paziente nello spazio, questo gli permette di interagire con lambiente virtuale
senza dover agire su nessun dispositivo fisico quale ad esempio mouse, tastiera, joypads,
joysticks ecc.
3
Cuore della Patient Station il Game Engine IGER (Intelligent Game Engine for
Rehabilitation), sviluppato presso il Laboratorio di Sistemi Intelligenti Applicati del
Diparitmento di Informatica dellUnviersit degli Studi di Milano, un Game Engine basato su
Panda3D, che oltre a fornire le funzionalit classiche di un Game Engine, affronta una serie
di problematiche dovute alla necessit di monitorare ed adattarsi alle necessit del paziente,
analizzeremo queste problematiche nel dettaglio pi avanti.
- HOSPITAL STATION (HS): Questa stazione, viene utilizzata dalle strutture e dal personale
sanitario, permette di definire a distanza il programma personalizzato di esercizi che ogni
paziente deve affrontare, inoltre fornisce gli strumenti per monitorare e analizzare i
progressi dei singoli pazienti attraverso lelaborazione dei dati ricevuti dalle singole Patient
Stations.
- NETWORKING STATION (NS): Installata a livello regionale, la Networking Station, fornisce
funzionalit per lanalisi avanzata dei dati collezionati dalle esperienze di riabilitazione dei
singoli pazienti su tutte le strutture che utilizzano Rewire, questo permette di individuare e
collezionare percorsi riabilitativi comuni tra diverse strutture, creando una consistente
knowledge base, e permettendo cos di migliorare la qualit globale del servizio.
Attualmente REWIRE fornisce principalmente strumenti e minigiochi studiati per la riabilitazione
cognitiva in pazienti affetti da NSU (Negligenza Spaziale Unilaterale), o con disabilit fisiche post-
ictus.
Lo scopo ultimo quello di supportare e fornire strumenti riabilitativi adatti al maggior numero di
patologie e disabilit possibili.
2.b - IGER: Un game engine per la riabilitazione
bene, ai fini di comprendere al meglio il progetto descritto in questo documento, spendere due
parole su IGER, il game engine utilizzato allinterno della Patient Station di REWIRE.
Un game engine un sistema (software) disegnato per la creazione e lo sviluppo di videogiochi. Si
tratta, in sostanza, di una collezione di librerie che forniscono funzionalit atte a risolvere una serie
di problematiche comuni allo sviluppo di quasi tutti i videogiochi.
Tradizionalmente esso si compone di:
- Rendering Engine (o Renderer): componente che si occupa della generazione dei singoli
frame bidimensionali o tridimensionali a partire da modelli o sprites. il motore sul quale si
basa la generazine di qualsiasi genere di animazione allinterno del gioco.
- Engine Fisico: componente che si occupa di simulare la fisica allinterno del mondo virtuale
ricreato allinterno del videogioco.
- Collision Detection: ogni game engine deve fornire tool adeguati ed efficienti per la
rilevazione di qualsiasi tipo di collisione tra i modelli caricati allinterno del gioco.
- Tools opzionali: quali ad esempio, tool per la gestione dei suoni, le animazioni, lintelligenza
artificiale, input devices differenti e tutto ci che pu essere utile allo sviluppo di un
videogioco.
IGER eredita tutti questi aspetti dal game engine su cui si basa, PANDA3D.
Poich gli esercizi di riabilitazione possono essere molto diversi tra di loro e le abilit e bisogni dei
pazienti possono variare, i videogiochi per la riabilitazione devono potersi adattare alle esigenze dei
4
singoli utenti, e nel frattempo essere in grado di monitorare e archiviare ogni singolo movimento,
mantenendo il pi possibile invariata lesperienza di gioco da un paziente allaltro.
IGER aggiunge alle funzionalit standard di un game engine tradizionale:
- Tools standard: per la configurazione offline, da parte dei terapisti, dei singoli videogiochi
riabilitativi, permettendo di aggiustare i parametri che pi si ritengono opportuni alle
esigenze di un determinato paziente.
- Strumenti per il graduale adattamento automatico dei parametri di gioco per meglio
rispecchiare levoluzione delle abilit psicomotorie del paziente.
- Strumenti per il monitoraggio in tempo reale dei movimenti dei pazienti.
- Strumenti per lacquisizione e salvataggio dei dati di gioco sia per la valutazione dei progressi
del paziente sia per la motivazione.
Inoltre IGER fornisce un layer di astrazione sul device di Input, denominato IDRA (Input Device for
Rehabilitaion Abstraction layer) questo per potersi adattare al meglio alle esigenze del paziente:
Sar ad esempio pi facile utilizzare un joystick per un paziente affetto da NSU (Neglect) piuttosto
che per un paziente con qualche tipo di paralisi alle braccia. Daltro canto un dispositivo come la
Nintendo Wii Balance Board, non potr essere utilizzata da pazienti con qualche sorta di paralisi alla
parte inferiore del corpo.
Questo layer di astrazione sui dispositivi di Input permetter a qualsiasi paziente di giocare a
qualsiasi gioco della piattaforma, in quanto esso fornisce un interfaccia di input verso il gioco
comune a tutti i dispositivi.
Al momento i dispositivi supportati da IGER sono:
- Microsoft Kinect.
- Sony Playstation 3 Eye camera.
- Nintendo Wii Balance Board.
- Tyromotion Tymo.
- Motycon OpenGo Insoles.
- Phantom Omni.
- Novint Falcon.
- E in parte il Leap Motion Controller.
5
3 - RIABILITAZIONE DELLA MANO
Ispirandosi al modello fino a qui descritto, quello che si voluto fare in questo progetto stato
ricreare, in piccolo, questi sistemi applicandoli al caso specifico della riabilitazione della mano.
Questo progetto stato svolto in collaborazione con lunit di chirurgia della mano dellOspedale S.
Giuseppe di Milano, diretta dal Prof. Giorgio Pajardi. A questo progetto hanno partecipato anche la
Dott.ssa Erica Cavalli e la Dott.ssa Elena Mancon, le quali ci hanno invitato ad alcune sessioni di
riabilitazione con una paziente e aiutato a inquadrare il tipo di lavoro che avremmo dovuto svolgere
per realizzare il progetto. Per quanto riguarda il laboratorio AISLab, hanno collaborato al progetto il
Dott. Renato Mainetti e il Dott. Michele Pirovano.
Innanzi tutto bene inquadrare il target di pazienti considerato.
Abbiamo avuto la possibilit di sviluppare un mini-gioco riabilitativo per pazienti molto giovani (dai
quattro anni in su) affetti principalmente da agenesia delle dita della mano, o che hanno subito
traumi che hanno portato allamputazione parziale o totale delle dita.
Tali pazienti hanno subito un intervento di transfer delle falangi di alcune dita dei piedi al posto di
quelle amputate o mancanti: scopo di tale operazione quella di restituire al paziente, almeno
parzialmente, la funzionalit della mano, dando la possibilit di toccare e prendere oggetti.
Si tratta di un intervento particolarmente consigliato, specialmente a pazienti affetti da agenesia
delle dita, in quanto, essendo nati senza le dita della mano, e trovandosi nella fase iniziale di
apprendimento, che specialmente a quellet, particolarmente legata allinterazione con
lambiente circostante tramite il tatto e il contatto con gli oggetti, rischiano di sviluppare ritardi
nellapprendimento.
Anche in questo caso, la fase riabilitativa post-operatoria, particolarmente lunga, si tratta di periodi
di tempo dellordine di diversi anni e ha in questo caso due obbiettivi:
- Il primo, prettamente fisico, quello di esercitare il pi possibile le dita impiantate,
effettuando dei movimenti di avvicinamento e allontanamento delle dita, rotazione e presa
di oggetti.
- Il secondo, di carattere pi neurologico, consiste in una serie di esercizi atti a sviluppare la
consapevolezza nel bambino del nuovo arto e delle sue capacit.
Bisogna notare come il target di utenza sia profondamente differente da quello a cui si riferisce ad
oggi la piattaforma sviluppata allinterno del progetto REWIRE.
Mentre per REWIRE si ha a che fare con pazienti generalmente affetti da danni cerebrali dovuti a
ictus o a pazienti con problemi posturali o di movimento, in ogni caso adulti, in questo caso si ha a
che fare con pazienti molto giovani, bambini, per cui le tecniche di intrattenimento, e motivazione
del paziente vanno rivisitate in un'altra ottica.
E importante, soprattutto, strutturare i giochi in maniera diversa, tenendo il conto dellet
dellutente medio che lo andr ad utilizzare, in particolare:
- Il gameplay deve essere adattato alle capacit e allet del bambino, non bisogna proporre
nulla di molto complesso, ed fondamentale, per mantenere acceso linteresse del
bambino, che a ogni azione o movimento svolto in maniera corretta dal paziente
corrisponda un immediata risposta, divertente e stimolante del sistema.
- Gli obbiettivi stabiliti dal gioco devono essere quanto pi flessibili possibile e non vincolanti,
il modo in cui il bambino si approccer al gioco spesso imprevedibile, per tanto la
6
valutazione delle prestazioni e dei miglioramenti non potr essere misurata ad esempio
dalla quantit di obbiettivi raggiunti, quanto dallosservazione dei dati ottenuti dalle
misurazioni effettuate durante lintera sessione di gioco
- Il feedback fornito al paziente dal sistema sia in caso di movimento scorretto che di
motivazione deve essere studiato in maniera adeguata, ad esempio la figura del terapista
virtuale, usato con gli adulti in REWIRE ha poco effetto su un paziente di quattro anni, avr
sicuramente pi effetto uno smiley sullo schermo, piuttosto che fuochi dartificio, colori e
animazioni.
3.a - STRUMENTI DIGITALI GI UTILIZZATI NELLA RIABILITAZIONE DELLA MANO
A seguito dei primi incontri effettuati con i terapisti abbiamo potuto apprendere, che al momento,
vengono gi utilizzati in maniera del tutto sperimentale, dei videogiochi durante alcune sessione di
riabilitazione con il bambino.
Si tratta di giochi per tablet, generalmente iPad, sviluppati da terzi a scopo di intrattenimento. I
terapisti, con i genitori dei giovani pazienti, hanno analizzato alcune delle applicazioni offerte nei
vari App Store, scelto quelle che pi sembravano adatte al paziente in questione, e hanno provato
ad utilizzarle durante alcune sessioni riabilitative.
Questo tipo di approccio al problema porta sicuramente alcuni vantaggi:
- Innanzi tutto la moltitudine di applicazioni e giochi presenti nei vari store multimediali, offre
sicuramente unampia scelta, questo permette di trovare lapplicazione che pi riesce a
catturare linteresse del bambino e sar quindi pi facile mantenerlo concentrato
sullesercizio da svolgere.
- Lapplicazione installata disponibile per tutti, senza necessit di infrastrutture particolari,
come ad esempio un server ospedaliero per lo storage dei dati ottenuti dallapplicazione, o
sistemi di autenticazione e gestione dei diversi pazienti, questo permette in sostanza ai
genitori dei pazienti di installare sul proprio dispositivo la stessa applicazione provata in
ospedale, e fare giocare il bambino a casa per esercitare il pi possibile la mano da riabilitare
- Inoltre i costi relativi allacquisto di un gioco sullapp store sicuramente irrisorio rispetto a
quello di realizzazione di applicazioni ad hoc.
Vi sono per purtroppo una serie di svantaggi nellutilizzo di queste applicazioni commerciali,
pensate per lintrattenimento in ambito medico/riabilitativo:
- Spesso questi giochi non sono configurabili, non vi cio la possibilit da parte del terapista,
n di predisporre una tabella di esercizi da svolgere, n di impostare il singolo gioco in modo
da accettare unicamente il tipo di movimento desiderato.
- Questi giochi non sono pensati per adattarsi alle capacit fisiche del loro utente, ci significa
che generalmente un interazione errata viene interpretata come un errore, e il giocatore
viene semplicemente penalizzato; in realt, come si visto in precedenza analizzando le
funzionalit di IGER, nei videogiochi per la riabilitazione spesso necessario aggiustare
gradatamente i parametri di gioco in modo da adattarsi alle capacit del singolo paziente.
- Spesso utilizzando questi giochi necessaria la presenza fisica del terapista, in quanto il
gioco non pensato per assistere e correggere lutente in caso di movimenti sbagliati, inoltre
non si considera neanche laspetto motivazionale, per cui il paziente, rischia semplicemente
di rimanere frustrato da un insuccesso, e pu rifiutarsi di continuare, oppure pu giocare
controvoglia, aumentando cos il rischio di errore.
7
- Infine non viene fornita ai terapisti un interfaccia per lanalisi dei dati acquisiti durante il
gioco, riguardanti i movimenti effettuati, per cui non possibile monitorare eventuali
progressi o peggioramenti del paziente.
3.b - OBIETTIVO DEL PROGETTO
Alla luce di quanto descritto finora, a seguito degli incontri preliminari avuti coi terapisti, stato
stabilito lobbiettivo del progetto da realizzare:
Un prototipo di mini-gioco per pazienti a cui sono state gi impiantate due dita, lesercizio sar quello
di avvicinare le dita come per pizzicare (pinching) lo schermo di un dispositivo touch screen (nel
caso specifico dei test eseguiti, si tratta di un tablet), lapplicazione dovr reagire sia
allavvicinamento che allallontanamento delle dita (pinch-in e pinch-out), dovr essere
configurabile dal terapista tramite un opportuna interfaccia, e dovr essere in grado di registrare i
movimenti effettuati durante lintera sessione di gioco, i dati raccolti dovranno poi essere presentati
al terapista mediante un opportuna interfaccia in grado di evidenziare eventuali miglioramenti o
peggioramenti delle abilit motorie del paziente.
Lintero sistema di monitoraggio dovr essere trasparente al paziente, e il sistema di feedback in-
game dovr essere adattato per essere di facile comprensione a bambini molto piccoli.
Il prototipo verr realizzato utilizzando HTML5 e Javascript e verr installato su un webserver in
universit, lapplicazione verr quindi resa disponibile alla struttura e testata su un campione di
pazienti scelto a discrezione dei terapisti.
8
4 - STRUMENTI SOFTWARE UTILIZZATI
Prima di addentrarsi nei dettagli dello sviluppo del progetto, bene parlare degli studi che sono stati
effettuati su tecnologie gi esistenti quali il game engine Panda3D, il software di modellazione 3D
Blender, e le API del Leap Motion controller, scopo di tali studi stato quello di prendere confidenza
con alcuni degli strumenti utilizzati, ad oggi nello sviluppo di videogiochi sia allinterno del progetto
REWIRE che in ambito commerciale.
5 - PANDA 3D
Panda 3D un game engine, un framework open source per il rendering 3D e lo sviluppo di
videogiochi. Il nucleo scritto in C++ e le sue funzionalit possono essere estese utilizzando il
linguaggio di scripting Python.
Tra le features offerte ci sono:
- Renderer 3D che utilizza sia le librerie Mircrosoft DirectX su Microsoft Windows, che le
librerie OpenGL, compatibili con vari sistemi operativi
- Librerie per la gestione dellaudio
- Un physic engine integrato (oltre a supportarne di pi complessi, come ad esempio lNvidia
Physx engine) che fornisce API per la gestione dei problemi pi comuni nello sviluppo dei
videogiochi, quali quello del collision detection.
- Un sistema di effetti particellari dedicato
- Un sistema per la gestione delle GUI, per la realizzazione ad esempio di menu di gioco, o
scritte o elementi grafici da mostrare sullo schermo durante la fase di gioco
- Una semplice libreria PandaAI per una gestione basilare dellintelligenza artificiale nel
gioco, che fornisce ad esempio strumenti per la ricerca di un oggetto nello spazio di gioco,
levitare gli ostacoli, il trovare e seguire percorsi per spostarsi da un punto a un altro ecc.
5.a - FUNZIONAMENTO LOOP DI GIOCO Il funzionamento basilare di un qualsiasi videogioco mai prodotto sempre il medesimo, e consiste
sostanzialmente in quattro fasi:
- Fase di inizializzazione (o init()): la fase in cui vengono istanziati e inizializzati tutti i
componenti che verranno utilizzati allinterno del videogioco, dal timer, ai giocatori, agli
oggetti inanimati, lambiente, suoni, luci ecc.
- Fase di input: la fase in cui vengono letti dallesterno gli input del giocatore (per esempio
il movimento di un joystick, la pressione di un tasto).
- Fase di aggiornamento (o update()): la fase in cui vengono modificati alcuni parametri di
gioco, come ad esempio la posizione dei giocatori.
- Fase di disegno (o draw()): la fase in cui viene effettivamente disegnato il frame che verr
mostrato al giocatore, con tutti i componenti e i modelli le cui propriet sono state definite
nelle fasi precedenti.
In genere la fase di inizializzazione, viene eseguita una sola volta, allavvio del gioco.
Dopo di che si entra in un ciclo (loop) infinito (in realt non proprio infinito, ma termina in
condizioni particolari, quali ad esempio la terminazione del gioco), che esegue alternativamente la
fase di aggiornamento e di disegno del frame.
9
La velocit con cui avviene questo ciclo, o meglio lintervallo di tempo trascorso tra due fasi di
disegno indica il frame rate del nostro gioco.
In Panda3D, lo schema descritto sopra ovviamente implementato, ma trasparente al
programmatore.
Linizializzazione di un nuovo gioco e il conseguente lancio del ciclo di Update e Draw viene fatto in
Python estendendo la classe ShowBase, che inizializza alcuni strumenti utili allo sviluppo del gioco
quali ad esempio:
- Il loader: utilizzato per caricare qualsiasi tipo di gameObject allinterno del nostro gioco, dai
modelli 3d, alle textures, ai suoni, ecc.
- Il render: che si occupa, di tutto ci che grafica allinterno del gioco
- Il taskMgr: per la gestione dei vari task da eseguire allinterno del gioco
- La camera: ovvero la telecamera di default che delimita larea attualmente visibile del gioco
E diversi altri componenti.
Inoltre la classe ShowBase, ci fornisce accesso al metodo run(), che in maniera del tutto trasparente
avvia il loop di gioco.
Tutta la logica che concerne il disegno del singolo frame in Panda3D gestita da un grafo di nodi, la
cui radice loggetto render (o render2D nel caso di giochi bidimensionali); sar sufficiente
impostare un nodo generato dal caricamento (tramite loader) di un qualsiasi modello
tridimensionale come figlio delloggetto render (o come figlio di uno dei suoi figli), affinch il
renderer di panda3D renderizzi loggetto nella scena.
Ci che particolarmente utile in questo schema di gestione dei nodi ad albero, che possibile
impostare parentele tra i diversi oggetti, in tal modo sar ad esempio possibile muovere, scalare o
ruotare un singolo oggetto, non solo in funzione dellorigine della scena visualizzata, ma anche in
funzione del suo genitore.
Ultimo componente degno di nota, utile a descrivere macroscopicamente il funzionamento di un
gioco creato con panda3D, il taskManager.
Initialize
10
Il TaskManager, implementa in parte il concetto che sta dietro al metodo update, descritto nel
capitolo precedente, si tratta di una struttura dati a cui si possono appendere funzioni, tali funzioni
verranno eseguite a ogni loop e serviranno per i pi disparati scopi, come ad esempio:
- Modificare la posizione della camera di gioco
- Modificare la rotazione del giocatore sulla scena
- Modificare qualsiasi parametro di gioco
- Aggiornare i punteggi
- Oppure semplicemente eseguire controlli per il debugging del gioco
Ecco un esempio di codice per realizzare una semplice animazione, di una sfera che ruota su se stessa
in panda3D.
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
class FirstGame (ShowBase):
def __init__(self):
# Call superclass constructor
ShowBase.__init__(self)
# Set default camera position
base.disableMouse()
self.camera.setPos(0,-10,0)
# Load a model
self.myModel = loader.loadModel("smiley.egg");
# Reparent the model to render so that it will be displayed in the scene
self.myModel.reparentTo(render)
# Attach a task to taskManager to make the spin
self.taskMgr.add(self.spinTheBall, "Spin The Ball Task")
# TASKS
def spinTheBall(self, task):
# Rotate by 20 degrees per second
angleDegrees = task.time * 20.0
self.myModel.setHpr(angleDegrees, 0,0)
return Task.cont
#Instantiate and launch the game
game = FirstGame()
game.run()
Una volta compresa la struttura di base di un gioco realizzato con panda3D si passati alla
realizzazione di semplici giochi di test, nei quali si cercato di mappare un movimento su uno spazio
bidimensionale, come quello del mouse, allinterno della scena di un gioco 3D, scopo di tale test
stato quello di capire come effettuare il mapping dellinput ricevuto da un dispositivo esterno
allinterno del gioco.
Per questo tipo di test, sono stati utilizzati due approcci differenti:
- Lutilizzo di una camera ortografica invece che proporzionale per inquadrare la scena, tale
approccio consente di mappare, senza distorsioni unarea allinterno di uno spazio
tridimensionale, su un piano.
- Lutilizzo della tecnica del Ray Casting, che permette di rilevare sfruttando il sistema di
collision detection integrato nel game engine, il punto sulla superficie nello spazio
tridimensionale sul quale ci si trova col puntatore del mouse.
Entrambe queste tecniche verranno descritte qui di seguito, ma per fare ci necessario prima
introdurre il sistema di collision detection in Panda3D.
11
5.b - COLLISION DETECTION IN PANDA3D
Il problema del rilevare le collisioni (Collision Detection), un problema chiave nello sviluppo di un
qualsiasi videogioco, sia esso bidimensionale che tridimensionale.
Ogni qual volta due oggetti si toccano, abbiamo una collisione, e se non vogliamo che, ad esempio,
una palla che cade da 10 metri, attraversi semplicemente la superficie e prosegua indisturbata la sua
caduta verso il nulla, dovremmo rilevare la collisione con il suolo e gestirla appropriatamente,
fermando ad esempio la palla allimpatto, o se stiamo realizzando un gioco fedele alle leggi della
fisica, la faccia rimbalzare pi volte fino a farla fermare completamente.
Esistono varie tecniche per rilevare in maniera pi o meno efficiente la collisione tra due oggetti nei
videogiochi.
In videogiochi bidimensionali molto semplici, spesso viene usato quello che in inglese viene
chiamato Box Collider:
Si tratta di costruire un quadrato invisibile attorno agli sprites su cui vogliamo rilevare la collisione
della stessa altezza e larghezza di entrambi gli oggetti, quando i due quadrati si intersecano, allora
si verificata una collisione.
In Panda3D, vengono forniti sostanzialmente due metodi per gestire il problema delle collisioni:
1. La creazione di geometria dedicata alla collisione.
2. Abilitare il rilevamento delle collisioni su tutta la geometria visibile.
Il primo metodo di pi complessa implementazione, in quanto necessario costruire una
geometria secondaria dedicata esclusivamente alla collision detection, ma pi efficiente in quanto i
poligoni su cui rilevare le collisioni sono, in genere, molti meno, di quelli presenti in tutta la scena di
gioco, e sono, di solito, anche figure poco complesse come cubi, sfere, ecc.
Questo metodo dunque pi adatto ad applicazioni finite, il secondo invece molto pi grezzo, ma
molto pi rapido da implementare.
Il secondo metodo, ovviamente, di pi facile gestione, ogni elemento che costituisce la geometria
visibile del gioco, pu collidere con qualsiasi altro elemento nel gioco, il vantaggio ovviamente
dovuto al fatto che non necessario costruire geometrie dedicate alla collision detection, lo
svantaggio, che i poligoni visibili allinterno di un gioco di media complessit pu essere spesso
molto elevato, per cui il gioco costruito pu risultare molto oneroso in termini di risorse di calcolo
richieste per gestire il rilevamento di collisioni su ognuno di essi.
In ogni caso in Panda3D, il sistema di collisioni ruota sostanzialmente attorno ai seguenti oggetti:
- CollisionSolids:
o CollisionSphere
o CollisionTube
o CollisionPlane
o CollisionPolygon
o CollisionRay []
Sono tutti i solidi, generalmente invisibili che costituiscono la collision geometry, se
volessimo ad esempio far collidere la palla rotante creata nel capitolo precedente con
qualche altro oggetto, allora dovremmo costruire una CollisionSphere invisibile attorno alla
nostra palla, delle stesse dimensioni della palla stessa, a quel punto su questo oggetto
riusciremmo a rilevare collisioni con altri collider.
12
- CollisionHandlers:
Ce ne sono di diversi tipi in Panda3D, il pi semplice il CollisionHandlerQueue, che
sostanzialmente si occupa di rilevare tutte le collisioni avvenute nella scena di gioco in un
dato istante di tempo e inserirle in una coda, consultabile dal programmatore, che potr
estrarre le diverse collisionEntries una per volta e gestirle nel modo che ritiene pi
appropriato.
- CollisionTraverser, che loggetto fondamentale del sistema di collisioni di Panda3D, si
tratta in sostanza di una struttura dati che colleziona al suo interno tutti i collider creati dal
programmatore nella scena: un collider sostanzialmente, una coppia oggetto
(generalmente un collisionSolid) / handler.
Ecco un esempio del sistema di collisioni di panda3D in funzione, le collisionSphere intorno alle due
sfere sono state scalate in modo da essere un po pi grandi dei modelli visibili, in modo da essere
facilmente visibili:
5.c - MAPPATURA DI INPUT BIDIMENSIONALE NELLO SPAZIO: CAMERA ORTOGRAFICA
Ora che abbiamo visto come funziona il sistema di collision detection in PANDA3D, possiamo tornare
al problema originario, ovvero quello di mappare il movimento del mouse, che avviene su un piano
bidimensionale, allinterno della scena di gioco in panda3D, mappato di default su un ambiente a 3
dimensioni.
La prima delle due tecniche elencate prima era quella della camera ortografica.
13
Il concetto che sta dietro a questa tecnica, quello di sostituire le lenti della camera che inquadra la
scena di gioco, che di default sono lenti a proiezione prospettica: che riprendono lambiente, come
farebbe una telecamera reale, o come farebbe locchio umano; con una lente ortografica, che
elimina di fatto gli effetti prospettici, mantenendo le linee di proiezione perfettamente parallele fra
di loro.
Leffetto ottenuto dallutilizzo di queste lenti, ovviamente, la perdita di percezione visiva della terza
dimensione, per cui ad esempio avvicinandosi o allontanandosi da un oggetto, esso non si
ingrandisce n si rimpicciolisce: questo ovviamente poco intuitivo, ma fornisce un grande
vantaggio, quello di poter scalare la scena inquadrata in modo da mappare in maniera diretta le
coordinate, del dispositivo di input su due dimensioni, nel nostro caso un mouse, allinterno della
scena di gioco.
Per testare questa tecnica stato realizzato un mini-gioco in cui una pallina doveva seguire il
puntatore del mouse allinterno di un percorso delimitato da dei muri laterali, quando la pallina
toccava uno dei muri si bloccava e il gioco terminava.
Analizziamo solo la parte di codice relativa al mapping del device allinterno della nostra scena:
Sappiamo che Panda3D mappa la posizione del mouse con dei valori decimali compresi tra -1 e 1 sia
sullasse delle ascisse che su quella delle ordinate, il nostro scopo dunque quello di montare le
lenti ortografiche, e regolare la dimensione della pellicola fino a quando anche le coordinate della
scena non sono comprese tra -1 e 1, in modo che a certe coordinate del mouse corrisponda il
medesimo punto nella scena.
stato definito un metodo setupCamera, che si occupa proprio di questo:
# This method prepare the camera
def setupCamera(self): # since this is a 2d game, we use Orthographic lenses, this should avoid
# perspective related issues with the mouse lens = OrthographicLens()
# we set the camera film size to fit 4/3 aspect ratio, x size is set to
# 2, because we want the coordinate system to be in the [-1, 1] range lens.setFilmSize(2,1.5)# setFilmSize sets the camera film size in spatial
units base.camNode.setLens(lens) # With Orthographic lenses, camera height doesn't really matters base.camera.setPos(0,0,10) base.camera.setHpr(0,270,0)
Il metodo che setta la dimensione della pellicola, e quindi definisce la dimensione dellarea ripresa,
setFilmSize.
Una volta definita la dimensione dellarea ripresa si tratter solamente di convertire le coordinate
del mouse, comprese tra -1 e 1 in coordinate spaziali, comprese tra -1 e 1 sullasse delle ascisse e -
0.75 e +0.75 sullasse delle ordinate (questo valore per le ordinate dipendente dallaspect ratio
della finestra di gioco,in questo caso 4/3), facciamo questo nel task del gioco che si occupa del
tracciamento del mouse.
La conversione che dobbiamo fare per lasse Y realizzata semplicemente sapendo che laspect ratio
della nostra finestra 4:3, per cui si tratter di prendere le coordinate del mouse ricevute dividerle
per 4 e moltiplicarle per 3, supponiamo ad esempio che il mouse si trovi in coordinate (0,1), allora
la nostra posizione nello spazio di gioco sar 1 / 4 = 0,25 * 3 = 0,75.
14
Vediamo la parte che ci interessa:
def trackMouse(self, task):
# Track the mouse only if it's in the window otherwise we get errors
if(base.mouseWatcherNode.hasMouse() == True and self.trackingEnabled == True):
mousePos = base.mouseWatcherNode.getMouse()
self.mouseVector = Vec3(mousePos.getX(), mousePos.getY(), 0)
# Mouse position in X goes from -1 to 1
tX = self.mouseVector.getX()
# Since camera aspect ratio is 4:3, mouse relative position in our world
# will be 4/3 of its absolute position
tY = (self.mouseVector.getY() / 4) * 3
newWaypoint = Point3(tX,tY,0)
# etc. etc. . . . . .
Ed ecco uno screenshot del gioco finito, da notare come la posizione della pallina corrisponda alle
attuali coordinate del puntatore del mouse:
5.d - MAPPATURA DI INPUT BIDIMENSIONALE NELLO SPAZIO: RAY CASTING
La tecnica della camera ortografica vista nel capitolo precedente, semplifica di molto il problema
della mappatura di devices bidimensionali, o che utilizzano semplicemente un sistema di coordinate
differente rispetto a quello di panda3D, allinterno della scena di gioco; ma allo stesso tempo
impedisce la realizzazione di giochi completamente tridimensionali: questo dovuto alla natura non
15
prospettica delle lenti ortografiche, che non permette di avere percezione della profondit e quindi
della distanza tra la camera e i vari oggetti.
La tecnica del ray casting, ci viene in soccorso nel momento in cui abbiamo necessit di rilevare il la
posizione del mouse, o di altri dispositivi allinterno di una scena tridimensionale.
Il procedimento consiste nel rilevare la posizione del mouse nel suo sistema di coordinate (-1,1) e
proiettare ortogonalmente alla superficie di gioco un raggio (un collisionRay in panda3D) dalla
telecamera: il punto in cui avviene la collisione col terreno, sar il punto su cui si trova il mouse nella
scena.
stato realizzato, anche in questo caso, un gioco simile a quello precedente, ma, questa volta,
utilizzando lenti prospettiche e inquadratura non esattamente ortogonale alla superficie.
Analizziamo anche in questo caso le parti di codice utili al fine di comprendere il funzionamento di
questa tecnica:
Innanzi tutto, quello che dobbiamo fare preparare il collisionRay che andr proiettato sulla
superficie di gioco, si tratta di aggiungere semplice geometria di collisione:
16
# This generates a collisionRay and attaches it to the active camera, then it
# returns a nodePath to that ray
def setupMouseRayCastingLogic(self):
collisionNode = CollisionNode('Mouse Ray collision node')
self.pickerRay = CollisionRay()
collisionNode.addSolid(self.pickerRay)
return base.camera.attachNewNode(collisionNode)
Da notare, lultima istruzione, in cui viene impostato il nodo relativo al nuovo collisionRay come figlio
del nodo della telecamera: questo viene fatto perch proprio da essa che faremo partire il nostro
raggio.
A questo punto la classe collisionRay, ci consente comodamente di settare la posizione e
lorientamento del nostro raggio tramite un comodo metodo setFromLens():
Tale metodo setta lorigine del collisionRay su cui viene chiamato nel punto corrispondente alle
coordinate nel range [-1,1] sul piano focale minimo (ovvero sul piano pi vicino allosservatore, che
verr messo a fuoco dalla camera) e lo proietter, perpendicolarmente a questo piano, per una
lunghezza virtualmente infinita.
A questo punto, se riusciremo a rilevare una collisione tra il raggio e la nostra superficie, allora il
punto di collisione sul terreno, sar il punto del gioco su cui il giocatore ha cliccato, potremmo quindi
rilevare levento e gestirlo di conseguenza.
# This tasks checks the mouse status, and eventually sets the tracked WayPoints
def mouseMonitor(self, task): # We check if the mouse is within the game window if(base.mouseWatcherNode.hasMouse() == True): mpos = base.mouseWatcherNode.getMouse() # Shoot a ray from the camera towards the surface self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) base.cTrav.traverse(render) if self.cHan.getNumEntries() > 0: # This is so that we get the closest object self.cHan.sortEntries() pickedObj = self.cHan.getEntry(0).getIntoNodePath() if(pickedObj.getName() == "Ground Collision Node"): pickedObjPoint = self.cHan.getEntry(0).getSurfacePoint(render)
# etc. etc. [. . .]
Come possibile osservare dal codice, anche in questo caso, si utilizza un semplice il
CollisionHandlerQueue per la gestione delle collisioni: si proietta il raggio invisibile verso la superficie
con setFromLens, si chiama il metodo traverse() di collisionTraverser per rilevare le collisioni, se sono
state rilevate delle collisioni con il collisionNode della superficie, allora il punto di collisione ovvero:
17
pickedObjPoint = self.cHan.getEntry(0).getSurfacePoint(render)
il punto su cui lutente ha cliccato, secondo il sistema di coordinate del nostro gioco.
Una volta presa analizzate le possibili tecniche per la gestione di input da diversi device in Panda3D,
il lavoro s concentrato sullo studio delle potenzialit e la possibilit di integrare allinterno del
game engine, un dispositivo di input differente, il Leap Motion Controller.
18
6 - LEAP MOTION CONTROLLER
Il Leap Motion Controller, un dispositivo di input, pensato e sviluppato per il tracciamento
dettagliato delle mani e di tutte le dita dellutente, senza richiedere nessuna forma di contatto fisico
con il dispositivo.
Il funzionamento molto simile a quello del Microsoft Kinect, ma a differenza di questultimo, il cui
scopo principalmente quello di tracciare lintero corpo degli utenti nel suo raggio dazione, larea
analizzata dal leap motion controller molto ristretta, questo permette di ottenere una risoluzione
superiore a quella di kinect, che pu lavorare, in near mode, a 1 metro di distanza dal soggetto,
contro il range di interazione di 7 - 25 cm del Leap, ci rende il dispositivo potenzialmente adatto a
tracciare i movimenti della mano e la posizione delle singole dita nel dettaglio.
6.a - PROGRAMMARE IL LEAP API
Leap Motion fornisce agli sviluppatori una serie di librerie scritte in diversi linguaggi per interfacciarsi
con il dispostivo: poich scopo dello studio effettuato era quello far funzionare il leap con Panda3D,
sono state analizzate le librerie Python.
Il concetto che sta dietro alla comunicazione con il leap, quello di creare una propria classe,
sottoclasse di Listener, che implementi le funzioni che vengono richiamate per gestire i diversi tipi
di eventi che possono essere sollevati dal device, vediamo i quelli fondamentali:
- on_init(): questa funzione viene chiamata quando il controller a cui il nostro listener
collegato, viene inizializzato: sar opportuno inserire qua tutta la logica di inizializzazione
della nostra classe
- on_connect(): questa funzione viene richiamata quando il dispositivo si connesso con il
software del leap motion ed pronto a inviare frame
- on_disconnect(): questa funzione esattamente opposta alla precedente, serve ad esempio
a gestire il caso in cui il dispostivo venga accidentalmente scollegato dal computer.
- on_exit(): questa funzione viene chiamata quando il nostro listener viene scollegato dal
controller attivo, qua implementeremo tutta la logica di deallocazione della nostra classe.
- on_frame(): questa la funzione pi importante, richiamata dallevento sollevato quando
viene ricevuto un nuovo frame dal dispositivo, allinterno di questa funzione dovremmo
compiere tutte quelle operazioni necessarie ad analizzare il singolo frame ricevuto, e ad
estrapolare tutte le informazioni necessarie, alla nostra applicazione finale, nel nostro caso,
il gioco costruito con panda3D, affinch essa risponda correttamente agli input dellutente.
Oltre alla classe Listener, la libreria proposta dal produttore del dispositivo, ci fornisce una serie di
classi che ci permettono di astrarre sui dati ricevuti dal dispositivo e di lavorare in comodit su aspetti
quali ad esempio, la posizione della normale del palmo della mano, il numero di dita rilevate, la
posizione della punta di un singolo dito, ecc.
Analizziamo quelle fondamentali:
- La classe FRAME: probabilmente la classe pi importante, essa contiene tutte le istanze di
tutti i singoli oggetti rilevati nel frame corrente, quali ad esempio: quante mani sono state
rilevate, quante dita, quanti strumenti (come matite, penne, ecc.), quanto grande al
momento larea monitorata dal dispositivo, i frame al secondo generati attualmente, ecc.
19
- La classe HAND: fornisce informazioni su una singola mano rilevata dal dispositivo, da
informazioni riguardo, la posizione del palmo, la direzione della normale, se si sta muovendo
e se s in quale direzione e con che velocit, quante dita della mano sono state rilevate ecc.
- La classe POINTABLE: fornisce informazioni analoghe a quelle della classe HAND, ma per il
singolo dito della mano, o per il singolo tool rilevato. Le classi FINGER e TOOL estendono la
classe POINTABLE.
Le classi disponibili nella libreria, sono molte di pi, ma queste sono quelle fondamentali.
bene inoltre spendere qualche parola su un altro elemento fondamentale dellhand tracking: le
gestures.
Per gesture si intende un tipo di movimento molto comune, ricorrente o che ha un intenzione
particolare che pu essere compiuto dallutente.
Il software del Leap in grado di riconoscere alcune di queste gestures, quali ad esempio la rotazione
della punta del dito formando un cerchio: Gesture.Circle, oppure la traslazione di un dito sul piano
orizzontale o verticale: Gesture.Swipe, o il movimento che simula la pressione di un pulsante
Gesture.KeyTap o Gesture.ScreenTap, per ognuna di queste gesture possibile definire una
serie di parametri per la validazione del tipo di movimento da rilevare, quali ad esempio velocit,
ampiezza e direzione del movimento per personalizzare il tipo di risposta del dispositivo in funzione
della nostra applicazione.
Al momento le librerie del Leap non forniscono strumenti ufficiali per la realizzazione di gestures
personalizzate, nonostante ci, in seguito verr descritto un test realizzato in panda3D per il
rilevamento della gesture Grabbing ovvero della presa di un oggetto col Leap Motion Controller.
Prima per descriviamo il primo test realizzato con il Leap Motion Controller:
6.b - PRIMI TEST
Scopo del test stato quello di prendere confidenza con le API fornite dal produttore del dispositivo,
si realizzata una semplice applicazione a riga di comando che a ogni frame verificava linclinazione
di una mano posizionata sopra il dispositivo e stampava su standard input stringhe come La mano
punta verso il basso di gradi oppure la mano inclinata verso sinistra di gradi, ecc.
Ovviamente il cuore di un applicazione cos semplice sar solamente limplementazione del metodo
on_frame(), di cui riportiamo il codice;
Il codice del main poco interessante, conterr unicamente la logica di inizializzazione del nostro
listener e un loop infinito, che manterr il programma attivo fino alla pressione di un tasto,
vediamo dunque la parte interessante:
20
# Questo l'evento che ci interessa realmente, ogni volta che il listener fa
polling sul leap genera un frame che contiene tutte le info
# su ci che il dispositivo riuscito a trackare
def on_frame(self, controller):
# Recupero il frame corrente
frame = controller.frame()
# Controllo che ci sia almeno una mano:
if(not frame.hands.is_empty):
print("%d Mano/i Rilevata/e" % (len(frame.hands)))
# Recupero la prima mano, hands un vettore
hand = frame.hands[0]
# la direzione della mano intesa dal palmo verso le dita
direction = hand.direction
# la normale del palmo della mano, un vettore che
# punta verso il basso
normal = hand.palm_normal
pitch = direction.pitch * Leap.RAD_TO_DEG
roll = normal.roll * Leap.RAD_TO_DEG
yaw = direction.yaw * Leap.RAD_TO_DEG
if(pitch > 0):
print("La mano punta verso l'alto di %f gradi" % (pitch))
else:
print("La mano punta verso il basso di %f gradi" % (pitch))
if(roll < 0):
print("La mano e' inclinata verso destra di %f gradi" % (roll))
else:
print("La mano e' inclinata verso sinistra di %f gradi" %
(roll))
if(yaw > 0):
print("La mano e' ruotata verso destra di %f gradi" % (yaw))
else:
print("La mano e' ruotata verso sinistra di %f gradi" % (yaw))
else:
print("Metti la mano sopra il leap!")
Come stato detto in precedenza, la callback on_frame viene richiamato dal software di tracking
fornito col leap motion controller, ogni volta che il dispositivo trasferisce un frame al computer:
per prima cosa utilizziamo il metodo frame della classe Controller per recuperare listanza del frame
corrente.
A questo punto con un semplice controllo sulla lista dimensione della lista di oggetti Hand nel frame
corrente decidiamo se stampare la scritta Metti la mano sopra il leap!, o meno.
Nel caso in cui la mano sia stata rilevata dal dispositivo, accediamo allattributo hands della classe
frame, che sostanzialmente una lista di mani, e estraiamo il primo elemento, ovvero la prima mano
rilevata.
Ricaviamo direzione e normale del palmo, e ricaviamo attraverso dei semplici attributi gli angoli di
inclinazione della mano (pitch, roll, yaw) che convertiamo da radianti a gradi, fatto ci
stampiamo le stringhe pi appropriate.
Ecco un esempio di output del programma:
21
Realizzato questo primo test, si cercato di utilizzare il leap motion controller allinterno di panda3D:
stato realizzato in Blender un semplice modello tridimensionale di un aeroplano, che, una volta
importato in panda3D, stato programmato per muoversi seguendo i dati rilevati a posizione e
inclinazione della mano sul leap motion controller.
Rispetto al test precedente, la differenza dovuta al fatto che questa volta non bastato limitarsi a
stampare i valori di inclinazione della mano ottenuti a ogni frame, ma si dovuto mantenere in
memoria i dati rilevati in un dato frame, fornendo i metodi necessari al recupero degli stessi
allinterno di panda3D.
Una delle difficolt riscontrate nellutilizzo del leap allinterno del loop di gioco stata quella di
sincronizzare linput ricevuto dal dispositivo con la frequenza di aggiornamento del gioco stesso. Il
problema dovuto al fatto che il leap, generalmente, genera frame a velocit diversa rispetto a
quella necessaria al completamento del ciclo di aggiornamento del gioco: per tanto, se ad esempio,
si cerca di accedere a un parametro impostato allinterno del leapListener in due punti del codice
nella nostra procedura di aggiornamento di gioco, si rischia di ottenere valori diversi: perch pu
accadere che nel tempo che abbiamo impiegato per arrivare alla seconda istruzione di accesso ai
dati di movimento della mano, il leap abbia generato un nuovo frame, e il dato precedente stato
sovrascritto.
Si pu affrontare tale problema in due modi:
- Sincronizzando il frame rate del gioco e del leap motion controller, cosa non banale, in
quanto bisognerebbe richiedere al gioco un frame rate costante, cosa che penalizzerebbe
calcolatori poco potenti che dovranno eseguire il gioco.
- Organizzando il codice del gioco in modo da richiedere il valore estratto dal leap una sola
volta per ciclo, e conservare quel valore fino a loop completato, eliminando cos qualsiasi
problema di concorrenza alla fonte.
stata adottata questa seconda strategia, analizziamo le parti fondamentali del codice in questo
secondo test:
22
Innanzi tutto dovremo scrivere un listener personalizzato in grado di ottenere per ogni frame i gradi
di rotazione della mano intorno ai tre assi, inoltre avremo bisogno della posizione normalizzata del
palmo della mano rispetto allarea scansionata dal dispositivo lungo lasse Z, questo ci permetter
di settare la velocit dellaereo in funzione della posizione della mano: pi la mano vicina al bordo
superiore dellarea scansionata, pi la velocit sar alta, pi si avviciner al bordo inferiore, pi la
velocit sar bassa.
Il nostro listener estender ovviamente la classe Leap.Listener, concentriamoci su due dei metodi da
implementare metodi:
Il metodo on_init() , come abbiamo visto prima, il luogo in cui bisogna implementare tutta la logica
di inizializzazione del nostro listener: poich dovremo poter accedere dal gioco ai dati sulla posizione
della mano, dovremo dichiarare e inizializzare dei campi ad accesso pubblico che conterranno i dati
rilevati a ogni frame.
def on_init(self, controller):
# Questo contiene il frame precedente, serve per rilevare le traslazioni
# della mano
self.prevFrame = None
self.handPitch = None
self.handRoll = None
self.handYaw = None
self.translationStatus = None
self.reversed_normalized_palm_position = None
print("Listener inizializzato...")
Come possibile osservare, i dati ottenuti riguardano beccheggio (pitch), rollio (roll) e
imbardata, (yaw) della mano.
Concentriamoci ora sul metodo pi importante del listener, on_frame(): come nel test precedente
dovremo accedere ai dati riguardanti la posizione rilevata della mano sopra il dispositivo e
aggiornare le i campi impostati dal metodo di inizializzazione.
I dati relativi alla rotazione della mano, vengono convertiti, anche in questo caso da radianti a gradi
per moltiplicando il loro valore per la costante Leap.RAD_TO_DEG = (180/) con lunico scopo di
semplificarne lutilizzo allinterno di panda3D.
Degno di nota anche il metodo normalized_point() della classe InteractionBox (classe che
rappresenta lattuale area scansionata dal dispositivo), tale metodo richiamato con argomento
hand.palm_position restituisce la posizione normalizzata della mano nello spazio in un sistema di
coordinate ([0,1],[0,1],[0,1]) dove 0 il punto allestremit inferiore dallarea nel range attuale del
dispositivo e 1 il punto allestremit superiore per ognuno dei 3 punti cardinali dello spazio.
Ecco di seguito il codice:
23
def on_frame(self, controller):
# Recupero il frame corrente
frame = controller.frame()
# Controllo che ci sia almeno una mano:
if(not frame.hands.is_empty):
# Recupero la prima mano, hands e' un vettore
hand = frame.hands[0]
# la direzione della mano intesa dal palmo verso le dita
direction = hand.direction
# E' la normale del palmo della mano, un vettore che punta verso il
# basso
normal = hand.palm_normal
# Rilevo l'attuale rotazione della mano
self.handPitch = direction.pitch * Leap.RAD_TO_DEG
self.handRoll = normal.roll * Leap.RAD_TO_DEG
self.handYaw = direction.yaw * Leap.RAD_TO_DEG
# Estraggo la posizione della mano sull'asse Z
interactionBox = frame.interaction_box
# Ottengo un vettore che rappresenta la posizione del palmo
# normalizzata in relazione all'attuale
# interaction_box
normalized_palm_position =
interactionBox.normalize_point(hand.palm_position)
# Il leap usa un sistema di coordinate per cui l'avanti e' 0
# e indietro e' 1, a me serve il contrario
self.reversed_normalized_palm_position =
1 - normalized_palm_position.z
else:
print("Metti la mano sopra il leap!")
self.prevFrame = frame
Costruito il nostro listener personalizzato, vediamo ora come utilizzare i dati ottenuti dal listener per
far muovere laeroplano in panda3D. Innanzi tutto in fase di inizializzazione del gioco necessario
istanziare il listener, facciamo ci nel costruttore della classe World, il cui scopo quello di creare il
nostro mondo di gioco, chiamando la funzione controllerSetup cos implementata:
def controllerSetup(self):
# Istanzio il listener e il controller
self.leapListener = MyLeapListener()
self.leap = Leap.Controller()
# Assegno il listener al controller
self.leap.add_listener(self.leapListener)
A questo punto accedendo alla variabile self.leapListener avremo accesso a tutti i campi pubblici
riguardanti linclinazione e la posizione della mano nello spazio impostati nel punto precedente.
Copia di questo oggetto viene quindi passata al costruttore della classe Player, il cui scopo quello
di visualizzare e gestire il movimento del giocatore.
24
def move(self, task):
# Get target values for pitch roll and yaw,
targetPitch = self.inputListener.handPitch;
targetRoll = self.inputListener.handRoll;
targetYaw = self.inputListener.handYaw;
# If values are set to None, simply terminate the task
if(targetPitch is None or targetRoll is None or targetYaw is None):
return task.cont
# Yaw and Roll values are inverted in leap, so
# we need to change their sign
targetRoll *=-1
targetYaw *=-1
# Get dt to move smoothly
dt = globalClock.getDt()
# We want to rotate smoothly towards the target so we don't
# simply set the player Hpr to the values
# obtained from the inputListener, but we rotate a certain
# number of degrees per second towards the target
# Smoothly change heading
if(self.playerRootNP.getH() < targetYaw):
newH = self.playerRootNP.getH() - self.yawSpd * dt
if(newH > targetYaw):
newH = targetYaw
if(self.playerRootNP.getH() > targetYaw):
newH = self.playerRootNP.getH() - self.yawSpd * dt
if(newH < targetYaw):
newH = targetYaw
else:
newH = self.playerRootNP.getH()
# Smoothly change pitch
if(self.playerRootNP.getP() < targetPitch):
newP = self.playerRootNP.getP() + self.pitchSpd * dt
if(newP > targetPitch):
newP = targetPitch
if(self.playerRootNP.getP() > targetPitch):
newP = self.playerRootNP.getP() - self.pitchSpd * dt
if(newP < targetPitch):
newP = targetPitch
# Smoothly change roll
if(self.playerRootNP.getR() < targetRoll):
newR = self.playerRootNP.getR() + self.rollSpd * dt
if(newR > targetRoll):
newR = targetRoll
if(self.playerRootNP.getR() > targetRoll):
newR = self.playerRootNP.getR() - self.rollSpd * dt
if(newR < targetRoll):
newR = targetRoll
# Rotate the plane
self.playerRootNP.setHpr(newH,newP,newR)
# Check Throttle
self.checkThrottle()
# This actually moves the plane
self.playerRootNP.setPos(self.playerRootNP, 0,
self.throttle * self.playerMaxSpd * dt,0)
self.throttleLabel.setText("Throttle: %.1f" %(self.throttle * 100))
return task.cont
Come possibile osservare dal codice del Move Player Task creato nella classe Player, la gestione
dellinput affrontata in maniera piuttosto semplice:
Per prima cosa si accede allinputListener e si salvano in variabili locali i valori di inclinazione della
mano rilevati dal dispositivo, in questo modo in caso il listener cambiasse tali valori perch il
dispositivo ha generato un nuovo frame, avremmo comunque dei dati consistenti per il nostro ciclo
di aggiornamento della posizione dellaeroplano.
25
A questo punto tramite semplici operazioni matematiche si convertono i dati ricevuti dal dispositivo
in dati utilizzabili allinterno del gioco, per fare un esempio, possibile osservare come i gradi di
rollio e imbardata dellaeroplano arrivino dal dispositivo con segno opposto a quello utilizzato
allinterno di panda3D, in questo caso tali valori vengono semplicemente moltiplicati per -1 prima di
essere utilizzati per il movimento del giocatore.
In realt questi dati, una volta convertiti potrebbero essere utilizzati direttamente come parametri
del metodo setHpr(H,P,R) della classe NodePath di panda3D per far corrispondere con un mapping
diretto alla posizione della mano lesatta posizione dellaeroplano.
Il problema di questo approccio che i movimenti dellaereo risulterebbero troppo repentini per
essere realistici in caso di movimenti molto rapidi della mano dellutente; il codice scritto qua sopra
cerca di ovviare al problema in maniera molto semplice: lattuale posizione della mano non la
posizione attuale dellaereo, ma la posizione in cui laereo deve arrivare.
Come possibile osservare, laereo ha delle velocit di rotazioni impostate per ogni asse: il valore
ricevuto in input langolo a cui laereo deve arrivare (ad esempio targetRoll), se la rotazione attuale
dellaereo inferiore o superiore rispetto allangolo obiettivo allora bisogna ruotare laereo verso
tale angolo della sua velocit.
In questo modo si ottiene un movimento molto pi fluido e naturale.
6.c - INTRODURRE NUOVE GESTURE GRABBING
Come stato detto nella parte di introduzione al Leap Motion Controller, al momento le API fornite
dal produttore del dispositivo non forniscono strumenti semplici per lintroduzione di gestures
personalizzate e le gestures rilevate di default dal dispositivo sono molto poche e limitate, in
26
particolare se si vogliono sviluppare giochi per la riabilitazione della mano, dove, a seconda della
disabilit da riabilitare, necessario rilevare movimenti diversi.
Si voluto perci esplorare la possibilit di rilevare movimenti non preimpostati, e il movimento
scelto per questi test un movimento molto comune, quello di Grabbing o presa di un oggetto.
Innanzi tutto bene spendere due parole sul perch rilevare questo movimento non un operazione
cos banale con il leap motion controller, per fare ci ci avvaliamo di uno strumento molto comodo
fornito con il software di gestione del dispositivo il visualizer:
Si tratta di un software che si interfaccia col dispositivo e ci fornisce una rappresentazione
tridimensionale di ci che il dispositivo sta rilevando nello spazio intorno a se in tempo reale.
Come possibile osservare dallimmagine, nel caso della presa, il dispositivo non riesce a rilevare la
presenza delle dita nel momento in cui esse si avvicinano troppo fra di loro: questo dovuto al fatto
che il dispositivo osserva lambiente da un'unica posizione: dal basso, ci significa che nel momento
in cui le dita cominciano a essere troppo vicine fra loro e sovrapposte, dal suo punto di osservazione,
al palmo, esso non pi in grado di rilevarle e di conseguenza la lista fingers della classe hand del
frame corrente indica 0 dita presenti.
Il problema che a questo punto ci si pone come rilevare un evento come il grabbing, basato
strettamente sulla distanza delle dita (che deve essere a ogni frame sempre minore) con un
dispositivo in cui le dita superato un certo angolo spariscono?
Ovviamente non si pu rilevare con certezza assoluta, ma si pu pensare alla seguente osservazione
statistica:
Se per un certo numero di frame, il dispositivo ha rilevato 5 dita, e magari per ognuno di essi, le
punte delle dita si stavano avvicinando e improvvisamente a un certo frame, tutte le dita sono
scomparse (e rimangono assenti anche nei frame successivi), allora c una buona probabilit (e si
tratta di una probabilit, non di una certezza) che sia stata effettuata una gesture di grabbing.
Scopo del test effettuato, era dunque scrivere una sotto-classe del Leap-Listener in grado di
segnalare, utilizzando questa tecnica di monitoring delle dita rilevate frame per frame nel tempo,
leventualit di una possibile gesture di presa, e il conseguente rilascio.
Per prima cosa bisogna identificare un modo per poter segnalare allutente leffettivo rilevamento
della gesture di grabbing, si potrebbe studiare un sistema ad eventi per cui a ogni gesture valida
rilevata si potrebbe sollevare un evento che potremmo gestire allinterno della nostra applicazione.
27
Un alternativa meno complessa, vista la semplicit del nostro test, quella di utilizzare un campo
pubblico del nostro listener (self.grab) di tipo booleano, che viene settata a true quando lutente ha
effettuato una presa e a false quando non lha effettuata oppure lha rilasciata.
Ci serviamo inoltre di una lista di interi che utilizzeremo per mantenere i dati relativi al numero di
dita rilevate in un certo numero di frame trascorsi.
Definiremo quindi un metodo catch_grab(hand) che verr chiamato allinterno del metodo
on_frame per rilevare se sulla mano in argomento stata rilevata la gesture di grabbing, e in caso
affermativo setter la variabile che abbiamo definito prima a true.
Vediamo come si comporta il metodo catch_grab(hand):
def catch_grab(self, hand):
# If we have at least one element in our finger_story list
if(not self.__finger_count_story is None):
# Let's sort the finger list, we just need to get the maximum finger
# number in the last 5 frames
self.__finger_count_story.sort()
max_finger =
self.__finger_count_story[len(self.__finger_count_story) - 1]
if(max_finger >= len(hand.fingers)):
# If the maximum finger number from the last 5 frames is 5, and
# now we got a 0, than this is a grab
if(max_finger == 5 and len(hand.fingers) == 0):
self.grab = True
print("GRAB")
# If grab is set to true, but we have five fingers in our
# current frame, than we should release the grab
if(self.grab == True and len(hand.fingers) == 5):
self.grab = False
print("GRAB RELEASED")
# This if-else statement simply updates the list
if(len(self.__finger_count_story) < 5):
self.__finger_count_story.append(len(hand.fingers))
else:
self.__finger_count_story.pop(0)
self.__finger_count_story.append(len(hand.fingers))
# If we didn't have any element in our finger story list,
# simply add one
else:
self.__finger_count_story = [len(hand.fingers)]
In questo caso la nostra lista: __finger_count_story contiene fino a 5 element0,i ovvero il numero
delle dita rilevate negli ultimi cinque frame, calcoliamo il numero massimo di dita rilevate in questi
frame: questo viene fatto per eliminare alcune rilevazioni fasulle dovute a eventuali elementi di
disturbo nellambiente scansionato dal leap, che possono per qualche frame far rilevare meno dita
di quelle che sono realmente sul dispositivo, in questo modo consideriamo il numero massimo di
dita rilevate in un dato frame con un valore attendibile del numero di dita che fino al frame scorso
erano effettivamente sul dispositivo.
A questo punto, come possibile osservare dal codice si tratta, semplicemente di confrontare il
numero ottenuto prendendo il massimo dalla lista, con il numero di dita rilevate nel frame corrente
e in particolare abbiamo che:
SE avevamo 5 dita fino al frame scorso e il numero di dita rilevate in questo frame 0 allora lutente
sta effettuando una presa.
Inoltre:
28
SE avevamo gi rilevato un evento di grabbing, quindi self.grab settato a True e ora rileviamo di
nuovo 5 dita sopra il dispositivo, allora la presa stata rilasciata.
A questo punto se in un ipotetico gioco Panda3D, in cui vogliamo rilevare la presa di un oggetto,
andiamo a controllare lo stato della variabile inputListener.grab, possiamo sapere se lutente sta
cercando di prendere qualcosa o meno.
Vediamo un esempio di esecuzione in un semplice gioco scritto in panda3D in cui utilizzando le
tecniche di raycasting viste in precedenza rileviamo su una superficie la posizione della mano, se
chiudiamo la mano scatenando levento di grabbing, allora una pallina sulla superficie comincer a
seguire la nostra mano:
6.d - IL LEAP MOTION CONTROLLER E LA RIABILITAZIONE
Dai test effettuati, il Leap Motion Controller si dimostrato essere uno strumento particolarmente
valido per la realizzazione di videogiochi per la riabilitazione della mano, in quanto permette un
tracciamento preciso e molto rapido della posizione di ogni singolo dito, del palmo, della velocit di
movimento e ci permette di sviluppare, con questi dati, moduli per il rilevamento di diverse
gestures adeguate per i singoli esercizi richiesti dai terapisti.
Nel caso specifico della riabilitazione della mano dei bambini, con cui abbiamo avuto a che fare in
questo periodo di lavoro, per, stato deciso di non adottare il dispositivo, almeno nella fase iniziale,
per i seguenti problemi riscontrati:
29
- Le dita impiantate sulla mano dei giovani pazienti, sono spesso troppo piccole per essere
rilevate con precisione dal dispositivo: spesso, il software di visualizzazione del leap motion
controller con cui abbiamo effettuato alcuni test, mostra unicamente il palmo della mano,
ci rende praticamente impossibile realizzare qualsiasi tipo di esercizio che coinvolga le dita
della mano.
- Il Leap Motion Controller certamente uno strumento di facile utilizzo, molto immediato: si
mette la mano sopra il dispositivo e succede qualcosa sullo schermo; per richiesta una
certa coordinazione mano-occhio che non da dare per scontata per utenti con meno di 5
anni: necessario infatti operare con la mano sopra al dispositivo, mentre allo stesso tempo
si osserva uno schermo che non si trova sotto al dispositivo, questo obbliga lutente a
operare sul leap senza guardarlo, il che porta spesso i bambini a spostarsi al di fuori del
raggio dazione del dispositivo rendendo non fluido linput del programma e difficile, e poco
preciso il rilevamento dei dati sul movimento effettuato.
- Questo fa s che un sistema basato su leap non sia cos facile da istallare e utilizzare in pratica.
Inoltre:
- Un problema di attrezzature: il Leap Motion Controller non funziona da solo, ha bisogno
almeno di un PC con sufficiente capacit hardware da gestire sia il software del Leap, che il
videogioco riabilitativo che lo utilizza. Inoltre, essendo lo strumento da realizzare studiato
per la riabilitazione a casa, necessaria una fase di configurazione e installazione dei
software relativi al Leap e al gioco, operazione che non sicuramente alla portata di
chiunque e che richiederebbe del personale dedicato, in grado di fornire il minimo di
assistenza necessaria a chi deve configurare lambiente.
- Un problema di costi: a differenza di molti altri dispositivi, come smartphone o tablet,
difficilmente un paziente possieder a casa un Leap Motion Controller, esso dovrebbe quindi
o essere fornito dalla struttura sanitaria o acquistato direttamente dal paziente, generando
un problema di costi, che si voluto evitare, quanto meno nella prima fase di
sperimentazione.
Il Leap Motion Controller rimane comunque uno strumento assolutamente valido per la
riabilitazione della mano in pazienti pi grandi, o per la riabilitazione cognitiva: ad oggi, infatti, il
dispositivo stato gi parzialmente integrato allinterno del Game Engine IGER, per quanto riguarda
il posizionamento del palmo e il tracciamento della posizione di un singolo dito o di un tool e andr
ad aggiungersi alla lista dei dispositivi supportati dalla piattaforma REWIRE.
30
7 - REALIZZAZIONE DEL GIOCO: HOT AIR BALLOON Per quanto riguarda il progetto descritto nelle prossime pagine si preferito utilizzare dei comuni
tablet, molto pi diffusi del Leap Motion Controller, per una serie di motivazioni:
- Abbiamo innanzi tutto potuto notare come i giovani pazienti abbiano gi sviluppato un
altissima dimestichezza nellutilizzo di questi dispositivi con applicazioni commerciali,
questo semplifica di molto la fase di apprendimento nellutilizzo dellapplicazione che verr
realizzata.
- Spesso i pazienti, o le loro famiglie, sono gi in possesso di uno di questi dispositivi, vista la
loro diffusione, ci permette di abbattere i costi.
- Inoltre i dispositivi multi-touch permettono di rilevare pi dita contemporaneamente sullo
schermo, il rilevamento molto preciso, e difficilmente le dita scompariranno senza che
lutente le sollevi realmente dal dispositivo.
Si cercato, come vedremo nel prossimo capitolo, di sviluppare unapplicazione che fosse
compatibile con il maggior numero di dispositivi, pertanto, lintero gioco stato sviluppato come
applicazione web in HTML5 e Javascript.
7.a - SCELTA DELLARCHITETTURA WEB-BASED
Le motivazioni di questa scelta sono molteplici:
Innanzitutto, volendo realizzare unapplicazione per la riabilitazione a casa a bassissimo costo, lidea
stata quella di dare la possibilit ai pazienti di sfruttare qualsiasi dispositivo di cui fossero gi in
possesso a casa, per utilizzare lapplicazione sviluppata, gli unici requisiti sarebbero stati una
connessione ad internet, un browser web e uno schermo touchscreen, di cui sono dotati ad oggi
tutti i pi comuni smartphone e tablet.
Inoltre prototipare un videogioco utilizzando le canvas di HTML 5 e javascript, molto pi rapido
che sviluppare lo stesso nativamente per ciascun dispositivo da supportare, questo ha permesso di
presentare ai terapisti in un tempo relativamente breve, un prototipo di gioco da testare sui pazienti.
Larchitettura web-based presenta inoltre una serie di vantaggi anche per quanto riguarda lo
sviluppo dellinterfaccia di configurazione e analisi dei dati da fare utilizzare ai terapisti.
Anche in questo caso non necessario installare nulla in ospedale per permettere ai terapisti di
accedere ai dati dei singoli pazienti, ma sufficiente sfruttare un qualsiasi terminale con accesso a
internet per accedervi. Tutti i dati dei pazienti vengono mantenuti anonimamente sul server e sono
sempre a disposizione dei terapisti
I vantaggi delladottare questa architettura sono quindi: completa indipendenza dal client, velocit
di sviluppo, gestione centralizzata dei dati dei pazienti, la possibilit di creare interfacce web per la
configurazione e analisi dei dati relativi ai pazienti in maniera molto rapida ed efficace.
Tale approccio presenta per alcuni svantaggi:
Innanzi tutto un gioco sviluppato per un browser web non pu essere utilizzato in assenza di
connessione a internet o con connessioni molto lente, ci pu non essere adatto per pazienti che
abitano in luoghi con accesso difficoltoso alla rete.
31
Le capacit delle librerie grafiche per web per quanto molto avanzate, sono ancora lontane
dallessere equiparabili a quelle disponibili per i singoli dispositivi, per tanto sar difficile realizzare
videogiochi particolarmente complessi per browser web.
Ad oggi esistono una serie di difficolt per quanto riguarda la riproduzione audio in videogiochi
basati sul web che vengono utilizzati su dispositivi mobili.
Inoltre lintera piattaforma sviluppata: gioco + pannello di configurazione + pannello di analisi ha
bisogno di funzionare su un webserver centralizzato, questo deve essere installato, gestito e
mantenuto direttamente dalla clinica che lo utilizza, tale gestione richiede personale competente e
quindi un potenziale costo per la struttura.
Detto ci, si comunque ritenuto opportuno utilizzare, almeno in questa fase preliminare questa
architettura, per rendere disponibile ai clinici e ai pazienti nel pi breve lasso di tempo possibile un
prototipo di piattaforma da testare e valutare per sviluppi futuri.
7.b - IL PROGETTO DA REALIZZARE
A seguito di una serie di incontri preliminari svolti con i chirurghi che si occupano di operare i
pazienti, con i fisioterapisti che si occupano della riabilitazione, con una piccola paziente di 4 anni e
i suoi genitori, stato deciso come procedere nella realizzazione del prototipo del primo videogioco.
La paziente, molto giovane, affetta da agenesia delle dita di una mano, aveva subito qualche mese
prima un operazione di transfer delle falangi di due delle dita dei piedi sulla mano.
Abbiamo potuto assistere a una sessione di riabilitazione:
Essa si divide sostanzialmente in due parti, una prima parte consiste in una serie di esercizi fisici in
cui al paziente, attraverso il gioco, vengono fatti maneggiare oggetti di diversa consistenza e
dimensione per realizzare costruzioni, tale processo serve a stimolare il processo di corticalizzazione
del nuovo arto.
La seconda parte, cognitiva, serve a fare prendere al paziente consapevolezza della sua nuova mano,
e del fatto che essa pu essere usata in maniera funzionale per diversi scopi.
Come gi accennato in precedenza, ci stato mostrato come i terapisti abbiano gi provato ad
utilizzare applicazioni commerciali per tablet allinterno della sessione di riabilitazione.
stato interessante osservare come la piccola paziente utilizzasse queste applicazioni: si trattava in
genere di giochi senza uno scopo preciso, a cui ad una qualsiasi azione corrispondeva una reazione:
applicazioni di disegno, o semplici giochi in cui toccando elementi della scena mostrata succedeva
qualcosa.
Tali applicazioni, come spiegato in precedenza, avevano il difetto di non richiedere un movimento in
particolare, per cui non potevano essere utilizzate per svolgere e valutare un esercizio in particolare,
ma solo per far esercitare e muovere la mano in libert alla paziente.
A seguito delle osservazioni svolte durante la sessione di riabilitazione, abbiamo avuto un colloquio
con i terapisti, con i quali abbiamo identificato un movimento da tracciare con il primo gioco da
realizzare.
Il movimento in questione quello di avvicinamento e allontanamento delle dita della mano a
pizzico (in inglese pinching): questo ad esempio il movimento, molto spesso richiesto, da
32
applicazioni per la gestione di fotografie, per la scalatura delle immagini: allontanando le dita si
zoomma ovvero si ingrandisce limmagine, avvicinandole si restringe.
Abbiamo quindi pensato di realizzare un semplice gioco, la cui protagonista una mongolfiera che
sale quando le dita di avvicinano, e scende quando si allontanano: scopo del gioco fare decollare
la mongolfiera, farla volare in un cielo pieno di uccellini da evitare e monetine da prendere, e quindi
farla atterrare dolcemente a destinazione.
Insieme al gioco stata sviluppata un interfaccia per la configurazione dei parametri relativi al
singolo paziente, e per lanalisi delle singole sessioni di gioco e della storia delle sessioni effettuate
Nei capitoli che seguiranno verranno descritte tutte le fasi di sviluppo e le problematiche affrontate
nello sviluppo di questo videogioco, e dellintera piattaforma per i terapisti.
7.c - HTML 5 TAG CANVAS E REALIZZAZIONE DEL LOOP DI GIOCO IN JAVASCRIPT
Elemento fondamentale per la realizzazione di videogiochi basati sul web ed eseguibili su un
qualsiasi browser web, lelemento Canvas.
Si tratta di un estensione dellHTML, che permette, tramite un linguaggio di scripting, nel nostro caso
Javascript, il rendering dinamico di immagini bitmap.
Il tag html canvas definisce un area di altezza e larghezza definiti su cui possibile, tramite API
javascript dedicate disegnare dinamicamente, cos come viene fatto utilizzando in altri ambiti API
per la grafica bidimensionale.
Di per s il tag canvas delimita unicamente un contenitore di grafica bidimensionale, e le API ad esso
associate sono unicamente API grafiche, il contenitore non predisposto di per se ad ospitare un
videogioco.
Come possibile, allora, realizzare animazioni sfruttando questo elemento?
Il concetto di per s abbastanza semplice:
Si scrive allinterno di una funzione, che dora in poi chiameremo DRAW, che verr richiamata
costantemente ogni tot millisecondi tramite la funzione javascript setInterval(function, time)
Questa funzione draw, non far altro che cancellare come prima cosa, lintero contenuto del canvas,
e ridisegnarlo subito dopo con opportune modifiche.
In questo modo genereremo una serie di frame, il cui framerate sar regolato dal parametro time
che passeremo alla funzione setInterval.
Trattandosi i giochi sostanzialmente di animazioni interattive, il pa
Top Related