Ovviamente leggere con GetState
va bene, ma rende molto difficile l'individuazione di gesti articolati, come le operazioni di trascinamento, il doppio tap, etc.
La possibilità di utilizzare gesti complessi e al tempo stesso "naturali" (come appunto trascinare un oggetto per farlo interagire con altri, "lanciarlo" fuori dallo schermo per indicare che non ci interessa, "pizzicare" lo schermo con due dita per ingrandire o rimpicciolire le immagini) sono fondamentali nel realizzare una sensazione di "interazione realistica" con le metafore rappresentate a schermo.
Per nostra fortuna, Windows Phone supporta una serie di tocchi predefiniti che dovrebbero soddisfare tutte o quasi le nostre esigenze. I più importanti sono:
Gesto | Descrizione |
---|---|
Tap | Tocco singolo; per selezionare un elemento, premere un bottone, sparare, muoversi verso una direzione, etc. |
DoubleTap | Doppio tocco rapido; per selezionare opzioni speciali, armi secondarie ovvero per compiere azioni simili a quelle del tap, ma meno frequenti, etc. |
Drag | Trascinamento, lungo uno (VerticalDrag e HorizontalDrag ) o entrambi gli assi (FreeDrag ); utile per trascinare oggetti dentro e fuori contenitori, per interagire con altri oggetti, etc. |
Flick | Il gesto di scorrere rapidamente il dito sullo schermo, utile ad esempio per "lanciare" un oggetto verso una certa direzione |
Pinch | Il gesto di pizzicare lo schermo con due dita, ad esempio per aumentare o diminuire lo zoom |
Touch and Hold | Il gesto di tenere premuto, ad esempio per far comparire un menu contestuale o per scorrere le opzioni |
Prima di poter processare l'input da touch device, è necessario decidere quali gesti vogliamo che vengano "intercettati" dal nostro device, attivandoli con la prorietà EnabledGestures di tipo GestureType
esposta dalla classe TouchPanel.
Per indicare quali gesti vogliamo attivare, è sufficiente aggiungerli uno di seguito all'altro separandoli mediante l'operatore logico OR ( |
):
TouchPanel.EnabledGestures = GestureType.Tap | GestureType.DoubleTap | ...
Attraverso questa proprietà, è anche possibile prevedere diverse configurazioni di tocchi a seconda dello stato in cui si trova il gioco (ad esempio, se siamo in un menu potremmo limitare la scelta al solo Tap
o DoubleTap
, mentre nel gioco vero e proprio potremmo attivare anche altri tipi di gesti).
È importante fare attenzione a non attivare troppi gesti (soprattutto se non siamo sicuri della loro utilità ai fini del nostro gioco), dal momento che il carico di lavoro per la CPU del device su cui eseguiamo il gioco potrebbe risultare eccessivo, con conseguenti costi in termini di performance e di batteria.
GestureType supporta tutti i gesti sopra descritti, con in più alcune varianti, quali DragComplete e PinchComplete, che indicano il momento in cui il relativo gesto può essere considerato concluso:
public enum GestureType
{
None = 0,
Tap = 1,
DoubleTap = 2,
Hold = 4,
HorizontalDrag = 8,
VerticalDrag = 16,
FreeDrag = 32,
Pinch = 64,
Flick = 128,
DragComplete = 256,
PinchComplete = 512,
}
Prima di andare a leggere i gesti compiuti dall'utente è essenziale accertarci della presenza di gesti non ancora processati ricorrendo alla proprietà:
bool IsGestureAvailable { get; }
Una volta letto, infatti, un gesto non è più presente nel touchPanel e IsGestureAvailable
è su false
. Se provassimo a leggere il touch panel senza essersi preventivamente assicurati che il device sia effettivamente pronto a una nuova lettura otterremmo la seguente eccezione:
Per leggere il gesto, si utilizza il metodo statico esposto dalla classe TouchPanel
GestureSample ReadGesture();
Questo metodo, come si è detto, può essere invocato solo quando IsGestureAvailable
è true
. Ecco un esempio:
while (TouchPanel.IsGestureAvailable)
{
// legge il touchPanel
gesture = TouchPanel.ReadGesture();
}
Il metodo ReadGesture, come si vede, restituisce un oggetto di tipo GestureSample
, il quale contiene tutte le informazioni relative al gesto appena letto (nel caso in cui quest'ultimo non supporti determinate proprietà, i relativi campi verranno lasciati a zero):
Proprietà | Descrizione |
---|---|
GestureType GestureType {get;} |
Indica il tipo di gesto compiuto |
Vector2 Position {get;} |
Indica la posizione (in float) del primo dito lungo gli assi X e Y |
GestureType GestureType {get;} |
Supportato solo dal Pinch, indica la posizione del secondo dito lungo gli assi X e Y |
Vector2 Delta {get;} |
Indica lo spostamento del primo dito rispetto al punto iniziale. Nel Flick il delta viene utilizzato per indicare la distanza percorsa nell'unità di tempo (in pixels per second) |
Vector2 Delta2 {get;} |
Supportato solo dal Pinch, indica lo spostamento del secondo dito rispetto al punto iniziale) |
TimeSpan Timestamp {get;} |
Indica il momento temporale in cui il gesto è stato iniziato. Permette anche di ricostruire la durata del gesto ovvero l'intervallo tra un gesto e il successivo |