Kosketusohjaukset Windows Phone 7:n pelin kehittämisessä, osa 4, nipistys

Sivu päivitetty :
Sivun luontipäivämäärä :

Ohjelmointi! - 4.Nipistä, venytä asteikolle sprites

Tietoja tästä näytteestä

Nykyaikaisten älypuhelimien, kuten kuvankatseluohjelmien, avulla voit suurentaa ja kutistaa kuvaa kahdella sormella lisätäksesi tai pienentääksesi sormien välistä etäisyyttä. Voit tehdä saman Windows Phone 7:n Internet Explorerilla. Tätä toimintoa kutsutaan "nipistä, venytä" Windows Phone 7:ssä.

Nipistämisen ja venyttämisen lisäksi voit käyttää myös toimintoja, kuten "napauta" koskettaaksesi (napauttaaksesi) lyhyesti yhtä pistettä näytöllä ja "pyyhkäisemällä" jäljittääksesi näytön nopeasti. Näitä toimia kutsutaan yhdessä eleiksi.

Tässä ohjelmassa haluaisin suurentaa ja vähentää näytöllä näkyvää spriteä tällä puristus- ja venytystoiminnolla. Lisäksi viime kertaan asti sain suoraan kosketuspaneelin tiedot ja käsittelin niitä, mutta tällä kertaa haluaisin käsitellä kosketustoimintoja eleille omistetuilla menetelmillä.

Tämän esimerkkiohjelman tavoitteet

Nipistä ja venytä toimintoja suurentaaksesi ja kutistaaksesi spriteä.

図 1 :ストレッチでスプライトを拡大
Kuva 1: Venytä spriteä suurentaaksesi

Ohjelma - Kenttien ilmoittaminen

Kenttäilmoituksessa ei ole uutta luokkaa, mutta siinä on "tekstuurin keskikoordinaatti", "sprite-suurennus" ja "kahden viimeisen kosketusasennon välinen etäisyys puristettaessa".

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

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

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

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

Ohjelma - Eleiden ottaminen käyttöön

Tällä kertaa suoritamme vain eleitä sisältävän prosessin, mutta oletustilassa mitään eleitä ei voi käyttää. Jos haluat noutaa kunkin eleen tiedot, sinun on määritettävä ele käytettäväksi TouchPanel.EnabledGestures-ominaisuudessa.

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

Kaikkien eleiden ottaminen käyttöön vaikuttaa suorituskykyyn, joten varmista, että määrität vain ne eleet, joita haluat käyttää. Tässä "GestureType.Pinch" on asetettu hakemaan nipistystoimintotiedot ja "GestureType.PinchComplete" on asetettu osoittamaan, että nipistysprosessi on valmis. Asetussijainti asetetaan pelikonstruktorissa.

Ohjelma - Tekstuurien lataaminen

Tekstuurien lataaminen on sama kuin aiemmin, mutta tällä kertaa laskemme "tekstuurin keskikoordinaatin". Tämä johtuu siitä, että spriteä skaalattaessa se skaalautuu keskikoordinaatin kanssa origoksi.

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

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

Ohjelma - Hanki eletiedot

Saamme eletiedot (nipistä tästä) Game.Update-menetelmässä. Eleiden käsittely tapahtuu toistamalla niin monta elettä kuin olet ottanut käyttöön. "TouchCollection" -rakennetta, jota käytettiin viime kertaan, ei käytetä.

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

Tarkista while-silmukan TouchPanel.IsGestureAvailable-ominaisuuden tila eletietojen varalta ja tarkista, onko seuraavia eletietoja olemassa: Jos sinulla on seuraavat eletiedot, käytä "TouchPanel.ReadGesture" -menetelmää saadaksesi eletiedot.

"GestureSample.GestureType" tallentaa tietoja siitä, mikä eletyyppi sisältyy, joten haarautu prosessi siihen perustuvalla kytkinlausekkeella. Tässä esimerkissä konstruktori asettaa "GestureType.Pinch"- ja "GestureType.PinchComplete"-enumit "TouchPanel.EnabledGestures"-ominaisuuteen, joten ne ovat haarautuneita.

Ohjelma - Nipistyseleiden käsittely

On nopeampaa tarkastella koodin kommentteja siitä, mitä teemme, mutta yhteenvetona siitä, mitä teemme, löydämme eron kahden edellisen kosketuspisteen ja kahden pisteen välisen kosketuspisteen etäisyyden välillä tällä kertaa ja käytämme tätä eroa asteikon arvon lisäämiseen tai pienentämiseen.

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;

Kaksi kosketusasentoa voidaan saada "GestureSample.Position" ja "GestureSample.Position2". Voit vähentää kahden saadun vektorin välisen eron ja löytää kahden pisteen välisen etäisyyden kutsumalla "Vector2.Length" -menetelmää.

Muuten, tässä määritellään edellinen etäisyys 0: ksi, kun puristusta ei suoriteta, joten prosessi haarautuu, kun puristus aloitetaan ja toisessa ja seuraavissa silmukoissa. Tämä johtuu siitä, että ensimmäistä puristuskertaa ei ole aikaisempaa etäisyyttä, joten ei tarvitse skaalata.

Tällä kertaa käytämme myös vain kahta ominaisuutta, "GestureSample.Position" ja "GestureSample.Position2", mutta on myös "GestureSample.Delta" ja "GestureSample.Delta2" -ominaisuuksia, jotka voivat saada erotiedot edellisestä kosketusasennosta. Kussakin on kaksi ominaisuutta, mutta tämä on tarkoitettu monikosketukselle, ja eleille, jotka käyttävät vain yhtä kosketusta, käytät ominaisuuksia ilman "2".

Ohjelma - Käsittely, kun nipistysele on valmis

Kun nipistysele on valmis (vapauttaen jommankumman sormen kosketuspaneelista), kahden edellisen pisteen välinen etäisyys asetetaan takaisin arvoon 0. Alun perin voi olla parempi käyttää erillistä lippua, mutta koska on fyysisesti mahdotonta koskettaa samaa asentoa kahdella sormella, 0: n etäisyys määritellään ei puristamiseksi. (Jos resoluutio on alhainen, voi olla mahdollista koskettaa samaa asentoa ...)

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

Ohjelma - Spritejen piirtäminen

En mene tässä liikaa yksityiskohtiin, koska kyse on vain spriten piirtämisestä, mutta sijoitin sprite näytön keskelle ja piirsin lasketun asteikon arvon suurentamalla ja kutistamalla sitä sprite-keskipisteen ollessa alkuperänä.

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

Yhteenveto tästä näytteestä

Tällä kertaa selitimme eleille omistetun prosessin. Näytteessä luomme vain puristusprosessin, mutta on myös "leffoja" ja "pitimiä". Jos haluat tietää, mitä eleitä on saatavilla, tutustu XNA Game Studio 4.0:n GestureType-enumien ohjeeseen.

Voit toteuttaa saman asian kosketustiedoista, jotka on saatu TouchPanel.GetState-menetelmästä käyttämättä elekohtaisia menetelmiä tai rakenteita, mutta siinä tapauksessa sinun on laskettava itse monikosketustunnuksen hallinnan, kosketusajan, leffojen jne. Elekohtaisia menetelmiä käyttämällä näitä toteutuksia voidaan yksinkertaistaa, ja on myös se etu, että kaikkia pelejä ja sovelluksia voidaan käyttää samalla tavalla.

Kun luot kosketuspaneeliprosessin itse, jos voit korvata samanlaisen prosessin eleenä, suosittelemme, että käytät tätä.

Ohjelmointi! - 5.Nipistä kiertääksesi spritejä

Tietoja tästä näytteestä

Puristaminen viittaa yleensä "puristamiseen" ja "venyttämiseen", mutta XNA Game Studio 4.0:n nipistysprosessi ei rajoita prosessia erityisesti näihin kahteen, joten voit myös suorittaa toimintoja, jotka kiertävät yhden kosketuspisteen toisen kosketuspisteen ympärille.

Tässä haluaisin kiertää spriteä tällä toimintamenetelmällä. Muuten, tällä kertaa ei ilmestynyt uusia menetelmiä tai luokkia, ja se perustuu edelliseen skaalaukseen.

Tämän artikkelin mallikoodin kuvauksessa jätetään pois samat osat kuin edellinen skaalausnäyte.

Tämän esimerkkiohjelman tavoitteet

Kiertämällä kahta kosketuspistettä sprite pyörii. Myös edellinen skaalaustoiminto toimii.

図 2 :タッチポイントを回してスプライトを回転させています
Kuva 2: Spriteä kiertämällä kosketuspistettä kääntämällä

Ohjelma - Kenttien ilmoittaminen

"Sprite-kiertomäärä" ja "Viimeinen kiertokulma" lisätään edelliseen skaalausohjelmaan. Kaikki kulmat lasketaan radiaaneina.

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

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

Ohjelma - kiertoprosessi

Kiertoprosessi suoritetaan puristuseleiden aikana samalla tavalla kuin skaalauksen aikana.

En mene liikaa yksityiskohtiin kierron laskemisesta, koska se on matemaattinen tarina, mutta voit saada kulmasäteen "Math.Atan2" -menetelmällä etsimällä erovektorin kosketuspisteestä 1 kosketuspisteeseen 2. Etsi ero saadun kulman ja aiemmin hankitun kulman välillä ja lisää se sprite-kiertokulmaan.

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

Ohjelma - Spritejen piirtäminen

Spritesin piirtämiseen ei ole suuria muutoksia. SpriteBacth.Draw-menetelmän viides argumentti asetetaan laskettuun kiertokulmaan.

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

Yhteenveto tästä näytteestä

Tällä kertaa yritin kiertää spriteä puristustoiminnolla. Emme käytä erityisesti uusia luokkia, mutta toivon, että ymmärrät, että voimme toteuttaa sovelletun käsittelyn tarjottujen toimintojen perusteella.

Lopulta

Kävimme läpi näytteitä ja esittelimme kosketusohjauksen toteutusta Windows Phone 7:n ja XNA Game Studio 4.0:n avulla. Sisältö sisälsi yhden kosketuksen ja usean kosketuksen kosketuksen tietojen keräämisen ja käsittelyn sekä käsittelyn kosketuseleiden manipuloinnilla elekohtaisilla menetelmillä.

Tällä kertaa olen keskittynyt kosketuspaneeliin, mutta on vielä joitain toimintoja, joita en ole vielä ottanut käyttöön. Windows Phone 7 sisältää XNA Game Studio 4.0:aan myös uusia syöttöominaisuuksia, kuten kiihtyvyysanturin syötteen ja äänisyötteen. On joitain mielenkiintoisia ominaisuuksia, joita en voinut esitellä tällä kertaa, joten nauti haluamiesi toimintojen tutkimisesta.