Érintéses műveletek a Windows Phone 7 játékfejlesztésében 4. rész Csippentés

Oldal frissítve :
Oldal létrehozásának dátuma :

Programozás! - 4.Csippentsd meg, nyújtsd ki a sprite-okat

A minta ismertetése

A modern okostelefonok, például a képnézegetők, lehetővé teszik a kép nagyítását és zsugorítását két ujjal az ujjak közötti távolság növelésére vagy csökkentésére. Ugyanezt megteheti a Windows Phone 7 rendszerű Internet Explorer böngészővel is. Ezt a műveletet "csippentésnek, nyújtásnak" nevezik a Windows Phone 7 rendszerben.

A csippentés és a nyújtás mellett olyan műveleteket is használhat, mint a "koppintás", hogy röviden megérintse (megérintse) a képernyő egy pontját, és "pöccintsen" a képernyő gyors nyomon követéséhez. Ezeket a cselekedeteket együttesen gesztusoknak nevezik.

Ebben a programban szeretném nagyítani és csökkenteni a képernyőn megjelenő sprite-ot ezzel a csippentés és nyújtás művelettel. Ezenkívül az utolsó alkalomig közvetlenül megszereztem az érintőpanel információit és feldolgoztam azokat, de ezúttal az érintési műveleteket a gesztusoknak szentelt módszerekkel szeretném kezelni.

A mintaprogram céljai

Csípje meg és nyújtsa be a műveleteket a sprite nagyításához és zsugorításához.

図 1 :ストレッチでスプライトを拡大
1. ábra: Nyújtsa ki a sprite megnagyobbításához

Program – Mezők deklarálása

A mezőnyilatkozatban nincs új osztály, de "a textúra középső koordinátája", "a sprite nagyítása" és "az utolsó két érintési pozíció közötti távolság csípéskor".

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

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

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

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

Program - Kézmozdulatok engedélyezése

Ezúttal csak gesztusokat tartalmazó folyamatot hajtunk végre, de az alapértelmezett állapotban egyik gesztus sem használható. Az egyes kézmozdulatok információinak lekéréséhez be kell állítania a TouchPanel.EnabledGestures tulajdonsághoz használni kívánt kézmozdulatot.

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

Az összes kézmozdulat engedélyezése hatással van a teljesítményre, ezért ügyeljen arra, hogy csak a használni kívánt kézmozdulatokat állítsa be. Itt a "GestureType.Pinch" a csippentési művelet információinak lekérésére, a "GestureType.PinchComplete" pedig azt jelzi, hogy a csippentési folyamat befejeződött. A beállítás helye a Játék konstruktorában van beállítva.

Program - Textúrák betöltése

A textúrák betöltése ugyanaz, mint korábban, de ezúttal a "textúra középső koordinátáját" számítjuk ki. Ennek az az oka, hogy egy sprite méretezésekor a középső koordinátával skálázódik origóként.

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

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

Program – Kézmozdulatokkal kapcsolatos információk lekérése

A gesztusinformációkat (csippentés itt) a Game.Update módszerben kapjuk. A kézmozdulatok feldolgozása annyi kézmozdulat megismétlésének formájában történik, amennyit engedélyezett. A legutóbbi alkalommal használt "TouchCollection" struktúra nem használatos.

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

Ellenőrizze a TouchPanel.IsGestureAvailable tulajdonság állapotát a while ciklusban a kézmozdulatok adataiért, és ellenőrizze, hogy a következő kézmozdulat-információk jelen vannak-e: Ha a következő kézmozdulatokkal rendelkezik, használja a "TouchPanel.ReadGesture" metódust a kézmozdulatok információinak lekéréséhez.

A "GestureSample.GestureType" információkat tárol arról, hogy melyik kézmozdulattípus szerepel benne, ezért ágaztassa el a folyamatot egy kapcsolóutasítással. Ebben a példában a konstruktor a "GestureType.Pinch" és a "GestureType.PinchComplete" enumokat a "TouchPanel.EnabledGestures" tulajdonságra állítja be, így azok elágazóak.

Program – Csippentő kézmozdulatok kezelése

Gyorsabb, ha megnézzük a kódban szereplő megjegyzéseket arról, hogy mit csinálunk, de összefoglalva, hogy mit csinálunk, ezúttal megtaláljuk az előző két érintkezési pont közötti távolság és a két pont közötti érintkezési pont távolsága közötti különbséget, és ezt a különbséget használjuk a skála értékének növelésére vagy csökkentésére.

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;

A két érintési pozíció a "GestureSample.Position" és a "GestureSample.Position2" segítségével érhető el. Kivonhatja a két kapott vektor közötti különbséget, és a "Vector2.Length" módszer meghívásával megtalálhatja a két pont közötti távolságot.

Egyébként itt az előző távolságot 0-ként határozzuk meg, ha a csípést nem hajtják végre, így a folyamat elágazó, amikor a csípés megkezdődik, valamint a második és az azt követő hurkokban. Ez azért van, mert a csípés első alkalommal nincs korábbi távolság, így nincs szükség méretezésre.

Ezenkívül ezúttal csak két tulajdonságot használunk, a "GestureSample.Position" és a "GestureSample.Position2" tulajdonságokat, de vannak "GestureSample.Delta" és "GestureSample.Delta2" tulajdonságok is, amelyek megkaphatják a különbség információit az előző érintési pozíciótól. Mindegyik két tulajdonság van, de ez a többérintéses műveletekre vonatkozik, és a csak egyetlen érintést használó kézmozdulatok esetében a "2" nélküli tulajdonságokat fogja használni.

Program – Kezelés, ha a csippentő kézmozdulat befejeződik

Amikor az összecsippentő kézmozdulat befejeződött (bármelyik ujját elengedve az érintőpanelről), az előző két pont közötti távolság 0-ra áll vissza. Eredetileg jobb lehet külön zászlót használni, de mivel fizikailag lehetetlen két ujjal megérinteni ugyanazt a pozíciót, a 0 távolságot úgy definiálják, hogy nem csíp. (Ha a felbontás alacsony, előfordulhat, hogy ugyanazt a pozíciót lehet megérinteni ...)

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

Program - Sprites rajzolása

Itt nem megyek bele túl sok részletbe, mert csak a sprite rajzolásáról van szó, de a sprite-ot a képernyő közepére helyeztem, és a számított skálaértéket úgy rajzoltam meg, hogy a sprite középpontjával mint eredettel nagyítottam és zsugorítottam.

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

A minta összefoglalása

Ezúttal elmagyaráztuk a gesztusoknak szentelt folyamatot. A mintában csak egy csipetnyi folyamatot hozunk létre, de vannak "pöccintések" és "tartások" is. Ha meg szeretné tudni, hogy milyen kézmozdulatok érhetők el, tekintse meg az XNA Game Studio 4.0 GestureType felsorolások súgóját.

Ugyanezt a dolgot a TouchPanel.GetState módszerből nyert érintési információkból is megvalósíthatja gesztusspecifikus módszerek vagy struktúrák használata nélkül, de ebben az esetben magának kell kiszámítania a multi-touch ID kezelés sebességét, az érintési időt, a pöccintéseket stb. A gesztusspecifikus módszerek használatával ezek a megvalósítások egyszerűsíthetők, és megvan az az előnye is, hogy minden játék és alkalmazás ugyanúgy működtethető.

Ha saját maga hoz létre érintőképernyős folyamatot, és egy hasonló folyamatot kézmozdulattal helyettesíthet, javasoljuk, hogy ezt használja.

Programozás! - 5.Csippentés a sprite-ok forgatásához

A minta ismertetése

A csippentés általában "csípésre" és "nyújtásra" utal, de az XNA Game Studio 4.0 csippentési folyamata nem korlátozza kifejezetten erre a kettőre a folyamatot, így olyan műveleteket is végrehajthat, amelyek az egyik érintkezési pontot egy másik érintkezési pont körül körözik.

Itt szeretném forgatni a sprite-ot ezzel a működési módszerrel. Egyébként ezúttal nem jelentek meg új módszerek vagy osztályok, és ez az előző skálázáson alapul.

A mintakód leírásában ebben a cikkben ugyanazok a részek vannak kihagyva, mint az előző méretezési minta.

A mintaprogram céljai

A két érintkezési pont elforgatásával a sprite forog. Az előző skálázási művelet is működik.

図 2 :タッチポイントを回してスプライトを回転させています
2. ábra: A sprite elforgatása az érintési pont elforgatásával

Program – Mezők deklarálása

A "Sprite forgatási mennyiség" és az "Utolsó forgási szög" hozzáadódik az előző méretezési programhoz. Minden szöget radiánban számítanak ki.

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

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

Program - Forgatási folyamat

Az elforgatási folyamat a csippentő kézmozdulatok során ugyanúgy történik, mint a méretezéskor.

Nem fogok túl sok részletbe belemenni a forgatás kiszámításával kapcsolatban, mert ez egy matematikai történet, de a szög radiánt a "Math.Atan2" módszerrel kaphatja meg, ha megtalálja a különbségvektort az 1. érintési ponttól a 2. érintéspontig. Keresse meg a kapott szög és az előzőleg megszerzett szög közötti különbséget, és adja hozzá a sprite forgási szögéhez.

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 - Sprites rajzolása

A sprite rajzolásában nincsenek jelentős változások. A SpriteBacth.Draw módszer ötödik argumentuma a számított forgási szögre van beállítva.

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

A minta összefoglalása

Ezúttal csippentéssel próbáltam forgatni a sprite-ot. Nem használunk különösebben új osztályokat, de remélem, megérti, hogy a rendelkezésre álló funkciók alapján megvalósíthatjuk az alkalmazott feldolgozást.

Végre

Végigjártuk a mintákat, és bemutattuk az érintéses műveletek megvalósítását a Windows Phone 7 és az XNA Game Studio 4.0 használatával. A tartalom magában foglalta az egyérintéses és többérintéses érintéses elérést és az érintési információk kezelését, valamint az érintéses kézmozdulatok manipulálásával történő feldolgozást gesztusspecifikus módszerekkel.

Ezúttal az érintőpanelre összpontosítottam, de még mindig vannak olyan funkciók, amelyeket még nem vezettem be. A Windows Phone 7 az XNA Game Studio 4.0 új beviteli funkcióit is tartalmazza, például a gyorsulásmérő bevitelét és a hangbevitelt. Van néhány érdekes funkció, amelyet ezúttal nem tudtam bevezetni, ezért kérjük, élvezze a használni kívánt funkciók felfedezését.