Jutiklinės sąveikos kuriant žaidimus, skirtus "Windows Phone 7" 4 dalies žiupsnelis

Puslapis atnaujintas :
Puslapio sukūrimo data :

Programavimo! - 4.Žiupsnelis, tempimas iki skalės spritų

Apie šį pavyzdį

Šiuolaikiniai išmanieji telefonai, pvz., vaizdų peržiūros priemonės, leidžia padidinti ir sumažinti vaizdą dviem pirštais, kad padidintumėte arba sumažintumėte atstumą tarp pirštų. Tą patį galite padaryti su "Internet Explorer" sistemoje "Windows Phone 7". Šis veiksmas "Windows Phone 7" vadinamas "žiupsnelis, tempimas".

Be suspaudimo ir tempimo, taip pat galite naudoti tokius veiksmus kaip "bakstelėjimas", kad trumpai paliestumėte (paliestumėte) vieną ekrano tašką ir "brūkštelėtumėte", kad greitai atsektumėte ekraną. Šie veiksmai bendrai vadinami gestais.

Šioje programoje norėčiau padidinti ir sumažinti ekrane rodomą sprite šia žiupsnelio ir tempimo operacija. Be to, iki paskutinio karto tiesiogiai gavau jutiklinio skydelio informaciją ir ją apdorojau, tačiau šį kartą norėčiau tvarkyti jutiklines operacijas naudodamas gestams skirtus metodus.

Šios pavyzdinės programos tikslai

Suimkite ir ištempkite operacijas, kad padidintumėte ir sumažintumėte sprite.

図 1 :ストレッチでスプライトを拡大
1 paveikslas: Ištempkite, kad padidintumėte sprite

Programa - laukų deklaravimas

Lauko deklaracijoje nėra naujos klasės, tačiau ji turi "tekstūros centrinę koordinatę", "sprite padidinimą" ir "atstumą tarp paskutinių dviejų prisilietimo padėčių, kai suspaudžiamas".

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

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

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

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

Programa - įgalinantys gestai

Šį kartą atliksime tik gestų procesą, tačiau numatytoje būsenoje nė vieno gesto negalima naudoti. Norėdami gauti informaciją apie kiekvieną gestą, turite nustatyti, kad gestas būtų naudojamas ypatybėje TouchPanel.EnabledGestures.

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

Visų gestų įjungimas turi įtakos našumui, todėl įsitikinkite, kad nustatėte tik tuos gestus, kuriuos norite naudoti. Čia "GestureType.Pinch" nustatyta gauti suspaudimo operacijos informaciją, o "GestureType.PinchComplete" nustatyta nurodyti, kad suspaudimo procesas baigtas. Nustatymo vieta nustatoma žaidimo konstruktoriuje.

Programa - Įkėlimo tekstūros

Tekstūrų įkėlimas yra toks pat kaip ir anksčiau, tačiau šį kartą skaičiuojame "tekstūros centrinę koordinatę". Taip yra todėl, kad keičiant sprite, jis skalauja mastelį su centro koordinate kaip kilme.

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

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

Programa - gaukite informaciją gestais

Mes gauname informaciją gestais (žiupsnelis čia) Game.Update metodu. Gestų apdorojimas atliekamas kartojant tiek gestų, kiek įjungėte. "TouchCollection" struktūra, kuri buvo naudojama iki paskutinio karto, nenaudojama.

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

Patikrinkite "TouchPanel.IsGestureAvailable" ypatybės būseną kilpoje, ar nėra informacijos apie gestą, ir patikrinkite, ar yra ši gesto informacija: Jei turite šią gesto informaciją, naudokite metodą "TouchPanel.ReadGesture", kad gautumėte gesto informaciją.

"GestureSample.GestureType" saugo informaciją apie tai, kuris gesto tipas yra įtrauktas, todėl šakokite procesą su jungiklio teiginiu, pagrįstu juo. Šiame pavyzdyje konstruktorius nustato "GestureType.Pinch" ir "GestureType.PinchComplete" enums į ypatybę "TouchPanel.EnabledGestures", todėl jie yra atitinkamai šakoti.

Programa - suspaudimo gestų valdymas

Greičiau pažvelgti į kodelyje esančius komentarus, ką darome, tačiau norėdami apibendrinti tai, ką darome, šį kartą randame skirtumą tarp ankstesnių dviejų jutiklinių taškų ir jutiklinio taško atstumo tarp dviejų taškų ir naudokite šį skirtumą, kad padidintume arba sumažintume skalės vertę.

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;

Dvi jutiklines pozicijas galima gauti atitinkamai naudojant "GestureSample.Position" ir "GestureSample.Position2". Galite atimti skirtumą tarp dviejų gautų vektorių ir rasti atstumą tarp dviejų taškų, vadindami "Vector2.Length" metodą.

Beje, čia mes apibrėžiame ankstesnį atstumą kaip 0, kai suspaudimas neatliekamas, todėl procesas yra šakotas, kai pradedamas suspaudimas ir antroje bei vėlesnėse kilpose. Taip yra todėl, kad pirmą kartą suspaudus, nėra ankstesnio atstumo, todėl nereikia keisti mastelio.

Be to, šį kartą naudojame tik dvi ypatybes: "GestureSample.Position" ir "GestureSample.Position2", tačiau taip pat yra "GestureSample.Delta" ir "GestureSample.Delta2" ypatybės, kurios gali gauti informaciją apie skirtumą nuo ankstesnės jutiklinės padėties. Yra dvi savybės, tačiau tai skirta kelių palietimų funkcijai, o gestams, kuriuose naudojamas tik vienas prisilietimas, naudosite savybes be "2".

Programa - tvarkymas, kai užbaigiamas suspaudimo gestas

Kai suspaudimo gestas bus baigtas (atleidžiant bet kurį pirštą nuo jutiklinio skydelio), atstumas tarp ankstesnių dviejų taškų vėl nustatomas į 0. Iš pradžių gali būti geriau naudoti atskirą vėliavą, tačiau kadangi fiziškai neįmanoma paliesti tos pačios padėties dviem pirštais, 0 atstumas apibrėžiamas kaip nesuspaudimas. (Jei skiriamoji geba maža, gali būti įmanoma paliesti tą pačią padėtį ...)

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

Programa - "Drawing Sprites"

Čia per daug nesigilinsiu, nes tai tik sprite piešimas, bet aš įdėjau sprite į ekrano centrą ir nupiešiau apskaičiuotą skalės vertę, padidindamas ir sumažindamas ją su sprite centru kaip kilme.

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

Šios imties santrauka

Šį kartą paaiškinome gestams skirtą procesą. Pavyzdyje mes sukuriame tik žiupsnelio procesą, tačiau taip pat yra "brūkštelėjimų" ir "laikų". Norėdami sužinoti, kokie gestai yra prieinami, peržiūrėkite "XNA Game Studio 4.0 Help for GestureType enums".

Tą patį galite įgyvendinti iš jutiklinės informacijos, gautos iš "TouchPanel.GetState" metodo, nenaudodami gestams būdingų metodų ar struktūrų, tačiau tokiu atveju turėsite patys apskaičiuoti kelių palietimų ID valdymo greitį, lietimo laiką, brūkštelėjimus ir kt. Naudojant gestams būdingus metodus, šie diegimai gali būti supaprastinti, taip pat yra pranašumas, kad visi žaidimai ir programos gali būti valdomi vienodai.

Kai patys kuriate jutiklinio skydelio procesą, jei panašų procesą galite pakeisti gestu, rekomenduojame jį naudoti.

Programavimo! - 5.Žiupsnelis, kad pasuktumėte spritus

Apie šį pavyzdį

Suspaudimas paprastai reiškia "suspaudimą" ir "tempimą", tačiau "XNA Game Studio 4.0" suspaudimo procesas konkrečiai neapriboja proceso šiais dviem, todėl taip pat galite atlikti operacijas, kurios apjuosia vieną jutiklinį tašką aplink kitą jutiklinį tašką.

Čia norėčiau pasukti sprite su tuo operacijos metodu. Beje, šį kartą neatsirado jokių naujų metodų ar klasių, ir tai pagrįsta ankstesniu mastelio keitimu.

Šiame straipsnyje pateiktame pavyzdžio kodo aprašyme praleidžiamos tos pačios dalys, kaip ir ankstesnis mastelio keitimo pavyzdys.

Šios pavyzdinės programos tikslai

Sukant du sąlyčio taškus, sprite sukasi. Ankstesnė mastelio keitimo operacija taip pat veikia.

図 2 :タッチポイントを回してスプライトを回転させています
2 paveikslas: "Sprite" pasukimas sukant sąlyčio tašką

Programa - laukų deklaravimas

"Sprite sukimosi suma" ir "Paskutinis sukimosi kampas" pridedami prie ankstesnės mastelio keitimo programos. Visi kampai skaičiuojami radianais.

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

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

Programa - rotacijos procesas

Sukimosi procesas atliekamas suspaudimo gestų metu taip pat, kaip ir keičiant mastelį.

Per daug nesigilinsiu į sukimosi skaičiavimą, nes tai matematikos istorija, tačiau kampo spindulį galite gauti naudodami "Math.Atan2" metodą, surasdami skirtumo vektorių nuo jutiklinio taško 1 iki jutiklinio taško 2. Raskite skirtumą tarp gauto kampo ir anksčiau įgyto kampo ir pridėkite jį prie sprite sukimosi kampo.

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

Programa - "Drawing Sprites"

Nėra jokių didelių pakeitimų, susijusių su spritų piešimu. Penktasis SpriteBacth.Draw metodo argumentas nustatomas pagal apskaičiuotą sukimosi kampą.

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

Šios imties santrauka

Šį kartą bandžiau pasukti sprite pagal žiupsnelio operaciją. Mes nenaudojame jokių naujų klasių, bet tikiuosi, kad suprantate, kad galime realizuoti taikomą apdorojimą pagal suteiktas funkcijas.

Pagaliau

Peržvelgėme pavyzdžius ir pademonstravome jutiklinės sąveikos įgyvendinimą naudojant "Windows Phone 7" ir "XNA Game Studio 4.0". Turinys apėmė lietimo informacijos gavimą vienu palietimu ir manipuliavimą vienu palietimu bei apdorojimą jutikliniais gestais, naudojant gestams būdingus metodus.

Šį kartą sutelkiau dėmesį į jutiklinį skydelį, tačiau vis dar yra keletas funkcijų, kurių dar nepristačiau. "Windows Phone 7" taip pat yra naujų "XNA Game Studio 4.0" įvesties funkcijų, pvz., akselerometro įvesties ir balso įvesties. Yra keletas įdomių funkcijų, kurių šį kartą negalėjau pristatyti, todėl mėgaukitės norimų naudoti funkcijų tyrinėjimu.