Interazioni tramite tocco nello sviluppo di giochi per Windows Phone 7 Parte 4 Pinch
Programmazione! - 4.Pinch, allungare per scalare gli sprite
Informazioni su questo esempio
Gli smartphone moderni, come i visualizzatori di immagini, consentono di ingrandire e ridurre un'immagine utilizzando due dita per aumentare o ridurre la distanza tra le dita. Puoi fare lo stesso con Internet Explorer su Windows Phone 7. Questa azione è chiamata "pizzicare, allungare" in Windows Phone 7.
Oltre a pizzicare e allungare, puoi anche utilizzare azioni come "toccare" per toccare brevemente (toccare) un punto sullo schermo e "scorrere" per tracciare rapidamente lo schermo. Queste azioni sono collettivamente indicate come gesti.
In questo programma, vorrei ingrandire e ridurre lo sprite visualizzato sullo schermo da questa operazione di pizzicamento e allungamento. Inoltre, fino all'ultima volta, ho ottenuto direttamente le informazioni del pannello touch e le ho elaborate, ma questa volta vorrei gestire le operazioni touch utilizzando metodi dedicati ai gesti.
Obiettivi di questo programma di esempio
Operazioni di pizzicamento e allungamento per ingrandire e restringere lo sprite.
Figura 1: Allungare per ingrandire lo sprite
Programma - Dichiarazione dei campi
Non c'è una nuova classe nella dichiarazione del campo, ma ha "la coordinata centrale della trama", "l'ingrandimento dello sprite" e "la distanza tra le ultime due posizioni di tocco quando si pizzica".
<summary>
テクスチャー
</summary>
Texture2D texture;
<summary>
テクスチャーの中心座標
</summary>
Vector2 textureCenterPos;
<summary>
スプライトのスケール
</summary>
float scale = 1;
<summary>
前回の 2 点間の距離
</summary>
float previousLength = 0;
Programma - Abilitazione dei gesti
Questa volta, eseguiremo un processo di solo gesto, ma nello stato predefinito, nessuno dei gesti può essere utilizzato. Per recuperare le informazioni su ogni gesto, è necessario impostare il gesto da utilizzare per la proprietà TouchPanel.EnabledGestures.
// タッチパネルでピンチのジェスチャーを有効にする
TouchPanel.EnabledGestures = GestureType.Pinch | GestureType.PinchComplete;
L'abilitazione di tutti i gesti influisce sulle prestazioni, quindi assicurati di impostare solo i gesti che desideri utilizzare. Qui, "GestureType.Pinch" è impostato per ottenere informazioni sull'operazione di avvicinamento delle dita e "GestureType.PinchComplete" è impostato per indicare che il processo di avvicinamento delle dita è completo. Il percorso dell'impostazione viene impostato nel costruttore Game.
Programma - Caricamento texture
Il caricamento delle texture è lo stesso di prima, ma questa volta stiamo calcolando la "coordinata centrale della trama". Questo perché quando si ridimensiona uno sprite, viene ridimensionato con la coordinata centrale come origine.
// テクスチャーをコンテンツパイプラインから読み込む
texture = Content.Load<Texture2D>("Texture");
// テクスチャーの中心座標を求める
textureCenterPos = new Vector2(texture.Width / 2, texture.Height / 2);
Programma - Ottieni informazioni sui gesti
Otteniamo informazioni sui gesti (pizzica qui) nel metodo Game.Update. L'elaborazione dei gesti è sotto forma di ripetizione di tutti i gesti che hai abilitato. La struttura "TouchCollection" utilizzata fino all'ultima volta non viene utilizzata.
// 次のジェスチャー情報が取得できる場合は true を返し続けます
while (TouchPanel.IsGestureAvailable)
{
// 次のジェスチャー情報を読み込みます
GestureSample gs = TouchPanel.ReadGesture();
switch (gs.GestureType)
{
case GestureType.Pinch:
// ここにピンチ処理を記述します
break;
case GestureType.PinchComplete:
// ここにピンチ完了処理を記述します
break;
}
}
Controllare lo stato della proprietà TouchPanel.IsGestureAvailable nel ciclo while per le informazioni sui gesti e verificare se sono presenti le seguenti informazioni sui gesti: Se si dispone delle seguenti informazioni sui gesti, utilizzare il metodo "TouchPanel.ReadGesture" per ottenere le informazioni sui gesti.
"GestureSample.GestureType" memorizza le informazioni sul tipo di gesto incluso, quindi diramare il processo con un'istruzione switch basata su di esso. In questo esempio, il costruttore imposta le enumerazioni "GestureType.Pinch" e "GestureType.PinchComplete" sulla proprietà "TouchPanel.EnabledGestures", in modo che siano rispettivamente ramificate.
Programma - Gestione dei gesti di pizzicamento
È più veloce guardare i commenti nel codice per quello che stiamo facendo, ma per riassumere ciò che stiamo facendo, troviamo la differenza tra la distanza tra i due punti di contatto precedenti e la distanza del punto di contatto tra i due punti questa volta e usiamo questa differenza per aumentare o diminuire il valore della scala.
case GestureType.Pinch:
// 現在の2点間の距離を求めます
float nowLength = (gs.Position - gs.Position2).Length();
if (previousLength == 0)
{
// 前回の2点間の距離が 0 の場合は
// 現在の2点間の距離を設定します
// 初回はスケール計算を行いません
previousLength = nowLength;
}
else
{
// 前回の2点間の距離との差分を計算します
float diffLength = nowLength - previousLength;
// ピンチ、ストレッチした距離に応じて
// スケールを変化させています
// 補正値は適当に設定します
scale = MathHelper.Max(scale + diffLength / 150, 0);
// 今回の距離を次の計算のために保持します
previousLength = nowLength;
}
break;
Le due posizioni di tocco possono essere ottenute rispettivamente con "GestureSample.Position" e "GestureSample.Position2". È possibile sottrarre la differenza tra i due vettori ottenuti e trovare la distanza tra i due punti chiamando il metodo "Vector2.Length".
A proposito, qui definiamo la distanza precedente come 0 quando il pizzicamento non viene eseguito, quindi il processo è ramificato quando viene avviato il pizzicamento e nel secondo ciclo e nei successivi. Questo perché la prima volta che pizzica, non c'è distanza precedente, quindi non è necessario scalare.
Inoltre, questa volta usiamo solo due proprietà, "GestureSample.Position" e "GestureSample.Position2", ma ci sono anche le proprietà "GestureSample.Delta" e "GestureSample.Delta2", che possono ottenere le informazioni sulla differenza dalla posizione di tocco precedente. Ci sono due proprietà ciascuna, ma questo è per il multi-touch, e per i gesti che usano solo un singolo tocco, userai le proprietà senza un "2".
Programma - Gestione al termine del gesto di avvicinamento delle dita
Quando il gesto di avvicinamento delle dita è completo (rilasciando uno dei due diti dal pannello a sfioramento), la distanza tra i due punti precedenti viene riportata a 0. Originariamente, potrebbe essere meglio usare una bandiera separata, ma poiché è fisicamente impossibile toccare la stessa posizione con due dita, la distanza di 0 è definita come non pizzicare. (Se la risoluzione è bassa, potrebbe essere possibile toccare la stessa posizione ...)
case GestureType.PinchComplete:
// ピンチが終了した場合は保持している距離を 0 に戻して
// 完了したことにします
previousLength = 0;
break;
Programma - Disegno Sprite
Non entrerò troppo nei dettagli qui perché si tratta solo di disegnare lo sprite, ma ho posizionato lo sprite al centro dello schermo e ho disegnato il valore della scala calcolato ingrandendolo e restringendolo con il centro dello sprite come origine.
// スプライトの描画準備
spriteBatch.Begin();
// スプライトを描画する
spriteBatch.Draw(texture,
new Vector2(graphics.PreferredBackBufferWidth / 2,
graphics.PreferredBackBufferHeight / 2),
null,
Color.White,
0.0f,
textureCenterPos,
scale,
SpriteEffects.None,
0.0f);
// スプライトの一括描画
spriteBatch.End();
Riepilogo di questo esempio
Questa volta, abbiamo spiegato il processo dedicato ai gesti. Nell'esempio, creiamo solo un processo di pizzicamento, ma ci sono anche "flick" e "holds". Per informazioni sui gesti disponibili, consultare la Guida di XNA Game Studio 4.0 per le enumerazioni GestureType.
È possibile implementare la stessa cosa dalle informazioni sul tocco ottenute dal metodo TouchPanel.GetState senza utilizzare metodi o strutture specifici dei gesti, ma in tal caso sarà necessario calcolare autonomamente la velocità di gestione dell'ID multi-touch, il tempo di tocco, i passaggi e così via. Utilizzando metodi specifici per i gesti, queste implementazioni possono essere semplificate e c'è anche il vantaggio che tutti i giochi e le applicazioni possono essere gestiti allo stesso modo.
Quando si crea un processo touch panel manualmente, se è possibile sostituire un processo simile come gesto, si consiglia di utilizzare questo.
Programmazione! - 5.Pinch per ruotare gli sprite
Informazioni su questo esempio
Il pizzicamento di solito si riferisce a "pizzicare" e "allungare", ma il processo di avvicinamento delle dita di XNA Game Studio 4.0 non limita specificamente il processo a questi due, quindi è anche possibile eseguire operazioni che circondano un punto di contatto attorno a un altro punto di contatto.
Qui, vorrei ruotare lo sprite con quel metodo operativo. A proposito, questa volta non sono apparsi nuovi metodi o classi e si basa sul ridimensionamento precedente.
Nella descrizione del codice di esempio in questo articolo, le stesse parti dell'esempio di ridimensionamento precedente vengono omesse.
Obiettivi di questo programma di esempio
Ruotando i due punti di contatto, lo sprite ruota. Anche l'operazione di ridimensionamento precedente funziona.
Figura 2: Rotazione dello sprite ruotando il touchpoint
Programma - Dichiarazione dei campi
"Quantità rotazione sprite" e "Ultimo angolo di rotazione" vengono aggiunti al programma di ridimensionamento precedente. Tutti gli angoli sono calcolati in radianti.
<summary>
スプライトの回転量(radian)
</summary>
float rotate;
<summary>
前回の回転角度(radian)
</summary>
float previousAngle;
Programma - Processo di rotazione
Il processo di rotazione viene eseguito durante i gesti di avvicinamento delle dita nello stesso modo in cui si esegue il ridimensionamento.
Non entrerò troppo nei dettagli sul calcolo della rotazione perché è una storia matematica, ma puoi ottenere il radiante angolare con il metodo "Math.Atan2" trovando il vettore differenza dal punto di contatto 1 al punto di contatto 2. Trova la differenza tra l'angolo ottenuto e l'angolo precedentemente acquisito e aggiungilo all'angolo di rotazione dello sprite.
switch (gs.GestureType)
{
case GestureType.Pinch:
//===== スケール計算 =====//
// 前回と同じなので省略
//===== 回転計算 =====//
// 2点間のベクトルを求めます
Vector2 pinchVector = gs.Position2 - gs.Position;
// Atan2 で角度を求めます
float nowAngle = (float)Math.Atan2(pinchVector.Y,
pinchVector.X);
if (previousAngle == 0)
{
// 前回の角度が 0 の場合は
// 現在の角度を設定します
// 初回は回転計算を行いません
previousAngle = nowAngle;
}
else
{
// 前回の角度との差分をスプライトの回転角度に加算します
rotate += nowAngle - previousAngle;
// 今回の距離を次の計算のために保持します
previousAngle = nowAngle;
}
break;
case GestureType.PinchComplete:
// ピンチが終了した場合は保持している距離、角度を 0 に戻して
// 完了したことにします
previousLength = 0;
previousAngle = 0;
break;
}
Programma - Disegno Sprite
Non ci sono modifiche importanti al disegno degli sprite. Il quinto argomento del metodo SpriteBacth.Draw è impostato sull'angolo di rotazione calcolato.
// スプライトの描画準備
spriteBatch.Begin();
// スプライトを描画する
spriteBatch.Draw(texture,
new Vector2(graphics.PreferredBackBufferWidth / 2,
graphics.PreferredBackBufferHeight / 2),
null,
Color.White,
rotate,
textureCenterPos,
scale,
SpriteEffects.None,
0.0f);
// スプライトの一括描画
spriteBatch.End();
Riepilogo di questo esempio
Questa volta, ho provato a ruotare lo sprite con l'operazione di pizzicamento. Non usiamo nuove classi in particolare, ma spero che tu capisca che possiamo realizzare l'elaborazione applicata in base alle funzioni fornite.
Finalmente
Abbiamo esaminato gli esempi e dimostrato l'implementazione delle interazioni tramite tocco utilizzando Windows Phone 7 e XNA Game Studio 4.0. Il contenuto includeva l'acquisizione tattile singola e multi-touch e la manipolazione delle informazioni tattili e l'elaborazione mediante manipolazione dei gesti tattili utilizzando metodi specifici dei gesti.
Questa volta, mi sono concentrato sul pannello a sfioramento, ma ci sono ancora alcune funzioni che non ho ancora introdotto. Windows Phone 7 include anche nuove funzionalità di input in XNA Game Studio 4.0, ad esempio l'input accelerometro e l'input vocale. Ci sono alcune caratteristiche interessanti che non ho potuto introdurre questa volta, quindi divertiti ad esplorare le funzioni che desideri utilizzare.