Dotykové interakcie pri vývoji hier pre Windows Phone 7, časť 4 štipka

Stránka aktualizovaná :
Dátum vytvorenia strany :

Programovanie! - 4.Štipka, natiahnite sa na stupnice spritov

O tejto vzorke

Moderné smartfóny, ako napríklad prehliadače obrázkov, vám umožňujú zväčšiť a zmenšiť obrázok pomocou dvoch prstov na zväčšenie alebo zmenšenie vzdialenosti medzi prstami. To isté môžete urobiť s Internet Explorerom vo Windows Phone 7. Táto akcia sa vo Windows Phone 7 nazýva "štipka, natiahnutie".

Okrem zovretia a naťahovania môžete tiež použiť akcie, ako napríklad "klepnutím" na krátke dotyky (klepnutie) na jeden bod na obrazovke a "rýchlym pohybom" na rýchle sledovanie obrazovky. Tieto akcie sa spoločne označujú ako gestá.

V tomto programe by som chcel zväčšiť a zmenšiť sprite zobrazený na obrazovke touto operáciou štipky a rozťahovania. Tiež som až do poslednej chvíle priamo získal informácie o dotykovom paneli a spracoval ich, ale tentokrát by som chcel zvládnuť dotykové operácie metódami určenými na gestá.

Ciele tohto vzorového programu

Operácie zovretia a natiahnutia, aby sa sprite zväčšil a zmenšil.

図 1 :ストレッチでスプライトを拡大
Obrázok 1: Natiahnite na zväčšenie šprotu

Program - Deklarovanie polí

Vo vyhlásení poľa nie je žiadna nová trieda, ale má "stredovú súradnicu textúry", "zväčšenie sprite" a "vzdialenosť medzi poslednými dvoma dotykovými polohami pri zovretí".

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

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

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

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

Program - Povolenie gest

Tentokrát vykonáme proces iba s gestami, ale v predvolenom stave nie je možné použiť žiadne z gest. Ak chcete načítať jednotlivé informácie o geste, musíte nastaviť gesto, ktoré sa má použiť pre vlastnosť TouchPanel.EnabledGestures.

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

Povolenie všetkých gest ovplyvňuje výkon, preto sa uistite, že nastavujete iba gestá, ktoré chcete použiť. Tu je nastavený "GestureType.Pinch" na získanie informácií o operácii štipkou a "GestureType.PinchComplete" je nastavený tak, aby označoval, že proces štipky je dokončený. Miesto nastavenia je nastavené v konštruktére hry.

Program - Načítanie textúr

Načítanie textúr je rovnaké ako predtým, ale tentoraz počítame "stredovú súradnicu textúry". Je to preto, že pri škálovaní sprite sa škáluje so stredovou súradnicou ako počiatkom.

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

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

Program - Získajte informácie o gestách

Dostávame informácie o gestách (štipka tu) v metóde Game.Update. Spracovanie gest je vo forme opakovania toľkých gest, koľko ste povolili. Štruktúra "TouchCollection", ktorá sa používala naposledy, sa nepoužíva.

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

Skontrolujte stav vlastnosti TouchPanel.IsGestureAvailable v slučke, kde nájdete informácie o gestách, a skontrolujte, či sú k dispozícii nasledujúce informácie o gestách: Ak máte nasledujúce informácie o gestách, na získanie informácií o gestách použite metódu "TouchPanel.ReadGesture".

"GestureSample.GestureType" ukladá informácie o tom, ktorý typ gesta je zahrnutý, takže proces rozvetvte pomocou príkazu prepínača na jeho základe. V tejto vzorke konštruktér nastaví enums "GestureType.Pinch" a "GestureType.PinchComplete" na vlastnosť "TouchPanel.EnabledGestures", takže sú rozvetvené.

Program - Manipulácia s gestami štipky

Je rýchlejšie pozrieť sa na komentáre v kóde, čo robíme, ale aby sme zhrnuli, čo robíme, nájdeme rozdiel medzi vzdialenosťou medzi predchádzajúcimi dvoma kontaktnými bodmi a vzdialenosťou dotykového bodu medzi týmito dvoma bodmi tentoraz a tento rozdiel použijeme na zvýšenie alebo zníženie hodnoty stupnice.

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;

Tieto dve dotykové polohy je možné získať pomocou "GestureSample.Position" a "GestureSample.Position2". Môžete odpočítať rozdiel medzi dvoma získanými vektormi a nájsť vzdialenosť medzi týmito dvoma bodmi volaním metódy "Vector2.Length".

Mimochodom, tu definujeme predchádzajúcu vzdialenosť ako 0, keď sa nevykoná zovretie, takže proces je rozvetvený pri spustení zovretia a v druhej a nasledujúcich slučkách. Je to preto, že pri prvom zovretí neexistuje žiadna predchádzajúca vzdialenosť, takže nie je potrebné škálovať.

Tentokrát tiež používame iba dve vlastnosti, "GestureSample.Position" a "GestureSample.Position2", ale existujú aj vlastnosti "GestureSample.Delta" a "GestureSample.Delta2", ktoré môžu získať informácie o rozdiele z predchádzajúcej dotykovej polohy. Každá z nich má dve vlastnosti, ale je to pre viacdotykové ovládanie a pre gestá, ktoré používajú iba jeden dotyk, použijete vlastnosti bez "2".

Program - Manipulácia po dokončení gesta zovretia

Keď je gesto zovretia dokončené (uvoľnenie ktoréhokoľvek prsta z dotykového panela), vzdialenosť medzi predchádzajúcimi dvoma bodmi sa nastaví späť na 0. Pôvodne môže byť lepšie použiť samostatnú vlajku, ale keďže je fyzicky nemožné dotknúť sa rovnakej polohy dvoma prstami, vzdialenosť 0 je definovaná ako nezovretie. (Ak je rozlíšenie nízke, je možné dotknúť sa rovnakej polohy ...)

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

Program - kreslenie spritov

Nebudem tu zachádzať do prílišných detailov, pretože je to len o kreslení sprite, ale sprite som umiestnil do stredu obrazovky a nakreslil vypočítanú hodnotu mierky zväčšením a zmenšením so stredom sprite ako pôvodu.

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

Zhrnutie tejto vzorky

Tentokrát sme vysvetlili proces venovaný gestám. Vo vzorke vytvárame iba proces štipky, ale sú tu aj "švihy" a "držania". Ak chcete zistiť, aké gestá sú k dispozícii, pozrite si pomocníka XNA Game Studio 4.0 pre GestureType enums.

To isté môžete implementovať z dotykových informácií získaných z metódy TouchPanel.GetState bez použitia metód alebo štruktúr špecifických pre gestá, ale v takom prípade si budete musieť sami vypočítať rýchlosť správy viacdotykového ID, čas dotyku, rýchle pohyby atď. Použitím metód špecifických pre gestá je možné tieto implementácie zjednodušiť a je tu tiež výhoda, že všetky hry a aplikácie je možné prevádzkovať rovnakým spôsobom.

Keď sami vytvárate proces dotykového panela, ak môžete podobný proces nahradiť gestom, odporúčame vám ho použiť.

Programovanie! - 5.Štipkou na otáčanie spritov

O tejto vzorke

Zovretie sa zvyčajne vzťahuje na "zovretie" a "natiahnutie", ale proces štipnutia XNA Game Studio 4.0 špecificky neobmedzuje proces na tieto dva, takže môžete vykonávať aj operácie, ktoré krúžia okolo jedného dotykového bodu okolo druhého dotykového bodu.

Tu by som chcel otočiť sprite s touto prevádzkovou metódou. Mimochodom, tentoraz sa neobjavili žiadne nové metódy ani triedy a je založená na predchádzajúcom škálovaní.

V popise vzorkovacieho kódu v tomto článku sa vynechávajú rovnaké časti ako predchádzajúca škálovacia vzorka.

Ciele tohto vzorového programu

Otáčaním dvoch dotykových bodov sa sprite otáča. Funguje aj predchádzajúca operácia škálovania.

図 2 :タッチポイントを回してスプライトを回転させています
Obrázok 2: Otáčanie spritu otáčaním dotykového bodu

Program - Deklarovanie polí

"Množstvo rotácie Sprite" a "Posledný uhol otáčania" sa pridajú k predchádzajúcemu programu škálovania. Všetky uhly sa počítajú v radiánoch.

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

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

Program - rotačný proces

Proces otáčania sa vykonáva počas gest zovretia rovnakým spôsobom ako pri škálovaní.

Nebudem zachádzať do prílišných podrobností o výpočte rotácie, pretože je to matematický príbeh, ale uhlový radián môžete získať metódou "Math.Atan2" nájdením vektora rozdielu z touchpointu 1 do touchpointu 2. Nájdite rozdiel medzi získaným uhlom a predtým získaným uhlom a pridajte ho k uhlu otáčania spritu.

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 - kreslenie spritov

V kreslení spritov nedochádza k žiadnym zásadným zmenám. Piaty argument metódy SpriteBacth.Draw je nastavený na vypočítaný uhol otáčania.

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

Zhrnutie tejto vzorky

Tentokrát som sa pokúsil otočiť sprite štipkou. Nepoužívame žiadne nové triedy, ale dúfam, že chápete, že môžeme realizovať aplikované spracovanie na základe poskytovaných funkcií.

Napokon

Prešli sme si ukážky a demonštrovali implementáciu dotykových interakcií pomocou Windows Phone 7 a XNA Game Studio 4.0. Obsah zahŕňal získavanie a manipuláciu s dotykovými informáciami jedným dotykom a viacdotykovým dotykom a spracovanie pomocou dotykových gest pomocou metód špecifických pre gestá.

Tentokrát som sa zameral na dotykový panel, ale stále existujú niektoré funkcie, ktoré som ešte nezaviedol. Windows Phone 7 obsahuje aj nové vstupné funkcie v XNA Game Studio 4.0, ako je vstup akcelerometra a hlasový vstup. Existuje niekoľko zaujímavých funkcií, ktoré som tentoraz nemohol predstaviť, takže si prosím užite skúmanie funkcií, ktoré chcete používať.