Interacțiuni tactile în dezvoltarea jocului pentru Windows Phone 7 Partea 4 Pinch

Pagina actualizată :
Data creării paginii :

Programare! - 4.Pinch, se întinde la scară sprites

Despre acest eșantion

Smartphone-urile moderne, cum ar fi vizualizatorii de imagini, vă permit să măriți și să micșorați o imagine folosind două degete pentru a mări sau micșora distanța dintre degete. Puteți face același lucru cu Internet Explorer pe Windows Phone 7. Această acțiune se numește "pinch, stretch" în Windows Phone 7.

În plus față de ciupire și întindere, puteți utiliza, de asemenea, acțiuni precum "atingeți" pentru a atinge scurt (atingeți) un punct de pe ecran și "glisați rapid" pentru a urmări rapid ecranul. Aceste acțiuni sunt denumite în mod colectiv gesturi.

În acest program, aș dori să măriți și să reduceți spritele afișate pe ecran prin această operație de prindere și întindere. De asemenea, până data trecută, am obținut direct informațiile panoului tactil și le-am procesat, dar de data aceasta aș dori să mă ocup de operațiile tactile folosind metode dedicate gesturilor.

Obiectivele acestui program de probă

Ciupiți și întindeți operațiile pentru a mări și micșora spritul.

図 1 :ストレッチでスプライトを拡大
Figura 1: Întindeți pentru a mări spritele

Program - Declararea domeniilor

Nu există o clasă nouă în declarația de câmp, dar are "coordonatele centrale ale texturii", "mărirea spritei" și "distanța dintre ultimele două poziții tactile la ciupire".

/// <summary>
/// テクスチャー
/// </summary>
Texture2D texture;

/// <summary>
/// テクスチャーの中心座標
/// </summary>
Vector2 textureCenterPos;

/// <summary>
/// スプライトのスケール
/// </summary>
float scale = 1;

/// <summary>
/// 前回の 2 点間の距離
/// </summary>
float previousLength = 0;

Program - Activarea gesturilor

De data aceasta, vom efectua un proces doar prin gesturi, dar în starea implicită, niciunul dintre gesturi nu poate fi folosit. Pentru a regăsi informațiile despre fiecare gest, trebuie să setați gestul de utilizat pentru proprietatea TouchPanel.EnabledGestures.

// タッチパネルでピンチのジェスチャーを有効にする
TouchPanel.EnabledGestures = GestureType.Pinch | GestureType.PinchComplete;

Activarea tuturor gesturilor afectează performanța, așa că asigură-te că setezi doar gesturile pe care dorești să le folosești. Aici, "GestureType.Pinch" este setat pentru a obține informații despre operațiunea pinch și "GestureType.PinchComplete" este setat pentru a indica faptul că procesul de prindere este finalizat. Locația de setare este setată în constructorul jocului.

Program - Încărcarea texturilor

Încărcarea texturilor este aceeași ca înainte, dar de data aceasta calculăm "coordonatele centrale ale texturii". Acest lucru se datorează faptului că atunci când scalarea unui sprite, se scalează cu coordonatele centrale ca origine.

// テクスチャーをコンテンツパイプラインから読み込む
texture = Content.Load<Texture2D>("Texture");

// テクスチャーの中心座標を求める
textureCenterPos = new Vector2(texture.Width / 2, texture.Height / 2);

Program - Obțineți informații despre gesturi

Obținem informații despre gesturi (ciupiți aici) în metoda Game.Update. Procesarea gesturilor este sub forma repetării cât mai multor gesturi pe care le-ați activat. Structura "TouchCollection" care a fost utilizată până ultima dată nu este utilizată.

// 次のジェスチャー情報が取得できる場合は true を返し続けます
while (TouchPanel.IsGestureAvailable)
{
  // 次のジェスチャー情報を読み込みます
  GestureSample gs = TouchPanel.ReadGesture();
  
  switch (gs.GestureType)
  {
    case GestureType.Pinch:
      // ここにピンチ処理を記述します
      break;
    case GestureType.PinchComplete:
      // ここにピンチ完了処理を記述します
      break;
  }
}

Verificați starea proprietății TouchPanel.IsGestureAvailable în bucla în timp ce pentru informații despre gesturi și verificați dacă sunt prezente următoarele informații despre gesturi: Dacă aveți următoarele informații despre gest, utilizați metoda "TouchPanel.ReadGesture" pentru a obține informațiile despre gest.

"GestureSample.GestureType" stochează informații despre ce tip de gest este inclus, astfel încât ramificați procesul cu o instrucțiune de comutare bazată pe acesta. În acest eșantion, constructorul setează enumerarile "GestureType.Pinch" și "GestureType.PinchComplete" la proprietatea "TouchPanel.EnabledGestures", astfel încât acestea să fie ramificate respectiv.

Program - Manipularea gesturilor de prindere

Este mai rapid să ne uităm la comentariile din cod pentru ceea ce facem, dar pentru a rezuma ceea ce facem, găsim diferența dintre distanța dintre cele două puncte de contact anterioare și distanța punctului de contact dintre cele două puncte de data aceasta și folosim această diferență pentru a crește sau a scădea valoarea scalei.

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;

Cele două poziții tactile pot fi obținute cu "GestureSample.Position" și respectiv "GestureSample.Position2". Puteți scădea diferența dintre cei doi vectori obținuți și puteți găsi distanța dintre cele două puncte apelând metoda "Vector2.Length".

Apropo, aici definim distanța anterioară ca 0 atunci când nu se efectuează ciupirea, astfel încât procesul este ramificat atunci când se începe ciupirea și în a doua și buclele ulterioare. Acest lucru se datorează faptului că prima dată de ciupire, nu există o distanță anterioară, deci nu este nevoie să scalați.

De asemenea, de data aceasta folosim doar două proprietăți, "GestureSample.Position" și "GestureSample.Position2", dar există și proprietățile "GestureSample.Delta" și "GestureSample.Delta2", care pot obține informații despre diferență față de poziția tactilă anterioară. Există două proprietăți fiecare, dar acest lucru este pentru multi-touch, iar pentru gesturile care folosesc doar o singură atingere, veți folosi proprietăți fără un "2".

Program - Manipularea atunci când gestul pinch se termină

Când gestul de prindere este complet (eliberând fiecare deget de pe panoul tactil), distanța dintre cele două puncte anterioare este setată înapoi la 0. Inițial, poate fi mai bine să utilizați un steag separat, dar din moment ce este fizic imposibil să atingeți aceeași poziție cu două degete, distanța de 0 este definită ca nefiind ciupită. (Dacă rezoluția este scăzută, este posibil să atingeți aceeași poziție ...)

case GestureType.PinchComplete:
  // ピンチが終了した場合は保持している距離を 0 に戻して
  // 完了したことにします
  previousLength = 0;
  break;

Program - Desen Sprites

Nu voi intra în prea multe detalii aici, pentru că este vorba doar despre desen sprite, dar am plasat sprite în centrul ecranului și a atras valoarea de scară calculată prin extinderea și micșorarea-l cu centrul de sprite ca 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();

Rezumatul acestui eșantion

De data aceasta, am explicat procesul dedicat gesturilor. În eșantion, creăm doar un proces de prindere, dar există și "flicks" și "holds". Pentru a afla ce gesturi sunt disponibile, consultați XNA Game Studio 4.0 Ajutor pentru enumerarea GestureType.

Puteți implementa același lucru din informațiile tactile obținute din metoda TouchPanel.GetState fără a utiliza metode sau structuri specifice gesturilor, dar în acest caz, va trebui să calculați singur viteza gestionării ID-ului multi-touch, timpul de atingere, loviturile etc. Prin utilizarea metodelor specifice gesturilor, aceste implementări pot fi simplificate și există, de asemenea, avantajul că toate jocurile și aplicațiile pot fi operate în același mod.

Când creați singur un proces de panou tactil, dacă puteți înlocui un proces similar ca gest, vă recomandăm să utilizați acest lucru.

Programare! - 5.Pinch pentru a roti sprites

Despre acest eșantion

Ciupirea se referă de obicei la "ciupire" și "întindere", dar procesul de prindere al XNA Game Studio 4.0 nu limitează în mod specific procesul la cele două, astfel încât să puteți efectua, de asemenea, operații care înconjoară un punct de contact în jurul unui alt punct de contact.

Aici, aș dori să rotiți sprite cu această metodă de operare. Apropo, nu au apărut metode sau clase noi de data aceasta și se bazează pe scalarea anterioară.

În descrierea codului eșantion din acest articol, sunt omise aceleași părți ca și eșantionul anterior de scalare.

Obiectivele acestui program de probă

Prin rotirea celor două puncte de contact, spritele se rotesc. Operațiunea anterioară de scalare funcționează, de asemenea.

図 2 :タッチポイントを回してスプライトを回転させています
Figura 2: Rotirea spritei prin rotirea punctului de contact

Program - Declararea domeniilor

"Suma de rotație Sprite" și "Ultimul unghi de rotație" sunt adăugate la programul de scalare anterior. Toate unghiurile sunt calculate în radiani.

/// <summary>
/// スプライトの回転量(radian)
/// </summary>
float rotate;

/// <summary>
/// 前回の回転角度(radian)
/// </summary>
float previousAngle;

Program - Procesul de rotație

Procesul de rotație se efectuează în timpul gesturilor de prindere în același mod ca și la scalare.

Nu voi intra în prea multe detalii despre calcularea rotației, deoarece este o poveste matematică, dar puteți obține radian unghiul cu metoda "Math.Atan2" prin găsirea vectorului diferență de la punctul de contact 1 la punctul de contact 2. Găsiți diferența dintre unghiul obținut și unghiul dobândit anterior și adăugați-l la unghiul de rotație al spritei.

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;
}

Program - Desen Sprites

Nu există modificări majore la desen sprites. Al cincilea argument al metodei SpriteBacth.Draw este setat la unghiul de rotație calculat.

// スプライトの描画準備
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();

Rezumatul acestui eșantion

De data aceasta, am încercat să rotească sprite prin operațiunea de prindere. Nu folosim clase noi în special, dar sper că înțelegeți că putem realiza procesarea aplicată pe baza funcțiilor furnizate.

În cele din urmă

Am trecut prin mostre și am demonstrat implementarea interacțiunilor tactile folosind Windows Phone 7 și XNA Game Studio 4.0. Conținutul a inclus achiziționarea și manipularea tactilă printr-o singură atingere și multi-touch a informațiilor tactile și procesarea prin manipulare prin gesturi tactile folosind metode specifice gesturilor.

De data aceasta, m-am concentrat pe panoul tactil, dar există încă unele funcții pe care nu le-am introdus încă. Windows Phone 7 include, de asemenea, noi caracteristici de intrare în XNA Game Studio 4.0, cum ar fi intrarea accelerometrului și intrarea vocală. Există câteva caracteristici interesante pe care nu le-am putut introduce de data aceasta, așa că vă rugăm să vă bucurați de explorarea funcțiilor pe care doriți să le utilizați.