Berøringsinteraktioner i spiludvikling til Windows Phone 7 Del 4 Pinch

Side opdateret :
Dato for oprettelse af side :

Programmering! - 4.Knib, stræk til skala sprites

Om denne prøve

Moderne smartphones, såsom billedfremvisere, giver dig mulighed for at forstørre og krympe et billede ved at bruge to fingre til at øge eller formindske afstanden mellem fingrene. Du kan gøre det samme med Internet Explorer på Windows Phone 7. Denne handling kaldes "pinch, stretch" i Windows Phone 7.

Ud over at klemme og strække kan du også bruge handlinger som "tryk" for kort at trykke (trykke på) et punkt på skærmen og "svirpe" for hurtigt at spore skærmen. Disse handlinger kaldes samlet gestus.

I dette program vil jeg gerne forstørre og reducere sprite, der vises på skærmen ved denne pinch and stretch-operation. Indtil sidste gang fik jeg også direkte oplysningerne om berøringspanelet og behandlede dem, men denne gang vil jeg gerne håndtere berøringsoperationer ved hjælp af metoder dedikeret til bevægelser.

Mål for dette prøveprogram

Knib og stræk operationer for at forstørre og krympe spritten.

図 1 :ストレッチでスプライトを拡大
Figur 1: Stræk for at forstørre spritten

Program - Erklæring af felter

Der er ingen ny klasse i felterklæringen, men den har "teksturens midterkoordinat", "forstørrelsen af spritten" og "afstanden mellem de sidste to berøringspositioner, når man klemmer".

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

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

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

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

Program - Aktivering af bevægelser

Denne gang udfører vi en proces, der kun er bevægelse, men i standardtilstanden kan ingen af bevægelserne bruges. Hvis du vil hente hver enkelt bevægelsesinformation, skal du angive den bevægelse, der skal bruges til egenskaben TouchPanel.EnabledGestures.

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

Aktivering af alle bevægelser påvirker ydeevnen, så sørg for kun at indstille de bevægelser, du vil bruge. Her er "GestureType.Pinch" indstillet til at få oplysninger om klemning, og "GestureType.PinchComplete" er indstillet til at indikere, at knibeprocessen er afsluttet. Indstillingsplaceringen er indstillet i spilkonstruktøren.

Program - Indlæsning af teksturer

Indlæsning af teksturer er den samme som før, men denne gang beregner vi "teksturens centerkoordinat". Dette skyldes, at når du skalerer en sprite, skalerer den med centerkoordinaten som oprindelse.

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

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

Program - Få oplysninger om bevægelser

Vi får gestusoplysninger (knib her) i Game.Update-metoden. Gestusbehandling er i form af gentagelse af så mange bevægelser, som du har aktiveret. "TouchCollection" -strukturen, der blev brugt indtil sidste gang, bruges ikke.

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

Kontroller tilstanden af egenskaben TouchPanel.IsGestureTilgængelig i mens loop for gestus oplysninger og kontrollere, om følgende gestus oplysninger er til stede: Hvis du har følgende bevægelsesoplysninger, skal du bruge metoden "TouchPanel.ReadGesture" til at få bevægelsesoplysningerne.

"GestureSample.GestureType" gemmer oplysninger om, hvilken gestustype der er inkluderet, så forgren processen med en switch-erklæring baseret på den. I dette eksempel indstiller konstruktøren enums "GestureType.Pinch" og "GestureType.PinchComplete" til egenskaben "TouchPanel.EnabledGestures", så de er forgrenede.

Program - Håndtering af knibebevægelse

Det er hurtigere at se på kommentarerne i koden for det, vi laver, men for at opsummere, hvad vi laver, finder vi forskellen mellem afstanden mellem de to foregående berøringspunkter og berøringspunktafstanden mellem de to punkter denne gang og bruger denne forskel til at øge eller mindske skalaværdien.

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;

De to berøringspositioner kan opnås med henholdsvis "GestureSample.Position" og "GestureSample.Position2". Du kan trække forskellen mellem de to opnåede vektorer og finde afstanden mellem de to punkter ved at kalde "Vector2.Length" -metoden.

Forresten, her definerer vi den forrige afstand som 0, når klemning ikke udføres, så processen er forgrenet, når klemning startes og i den anden og efterfølgende sløjfer. Dette skyldes, at første gang klemning ikke er nogen tidligere afstand, så der er ingen grund til at skalere.

Denne gang bruger vi også kun to egenskaber, "GestureSample.Position" og "GestureSample.Position2", men der er også "GestureSample.Delta" og "GestureSample.Delta2" egenskaber, som kan få forskelsoplysningerne fra den forrige berøringsposition. Der er to egenskaber hver, men dette er til multi-touch, og for bevægelser, der kun bruger enkelt berøring, vil du bruge egenskaber uden en "2".

Program - Håndtering, når knibebevægelsen er fuldført

Når knibebevægelsen er fuldført (frigør en af fingrene fra berøringspanelet), sættes afstanden mellem de to foregående punkter tilbage til 0. Oprindeligt kan det være bedre at bruge et separat flag, men da det er fysisk umuligt at røre ved den samme position med to fingre, defineres afstanden på 0 som ikke at klemme. (Hvis opløsningen er lav, kan det være muligt at røre ved samme position ...)

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

Program - Tegning af sprites

Jeg vil ikke gå for meget i detaljer her, fordi det bare handler om at tegne sprite, men jeg placerede sprite i midten af skærmen og tegnede den beregnede skalaværdi ved at forstørre og krympe den med midten af sprite som oprindelse.

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

Resumé af denne prøve

Denne gang forklarede vi processen dedikeret til bevægelser. I prøven opretter vi kun en klemmeproces, men der er også "flicks" og "holds". Du kan finde ud af, hvilke bevægelser der er tilgængelige, ved at se XNA Game Studio 4.0 Hjælp til GestureType-enums.

Du kan implementere det samme fra berøringsoplysningerne fra TouchPanel.GetState-metoden uden at bruge gestusspecifikke metoder eller strukturer, men i så fald skal du selv beregne hastigheden på multi-touch ID-styring, berøringstid, flicks osv. Ved at bruge gestus-specifikke metoder kan disse implementeringer forenkles, og der er også den fordel, at alle spil og applikationer kan betjenes på samme måde.

Når du selv opretter en berøringspanelproces, hvis du kan erstatte en lignende proces som en gestus, anbefaler vi, at du bruger denne.

Programmering! - 5.Knib for at rotere sprites

Om denne prøve

Klemning refererer normalt til "klemning" og "strækning", men XNA Game Studio 4.0's knibeproces begrænser ikke specifikt processen til disse to, så du kan også udføre handlinger, der cirkler et berøringspunkt omkring et andet berøringspunkt.

Her vil jeg gerne rotere sprite med den betjeningsmetode. Forresten dukkede ingen nye metoder eller klasser op denne gang, og det er baseret på den tidligere skalering.

I beskrivelsen af eksempelkoden i denne artikel udelades de samme dele som det forrige skaleringseksempel.

Mål for dette prøveprogram

Ved at rotere de to berøringspunkter roterer spritten. Den tidligere skaleringsoperation fungerer også.

図 2 :タッチポイントを回してスプライトを回転させています
Figur 2: Rotation af spritten ved at dreje berøringspunktet

Program - Erklæring af felter

"Sprite rotationsmængde" og "Sidste rotationsvinkel" føjes til det forrige skaleringsprogram. Alle vinkler beregnes i radianer.

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

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

Program - Rotationsproces

Rotationsprocessen udføres under knibebevægelser på samme måde som ved skalering.

Jeg vil ikke gå for meget i detaljer om beregning af rotationen, fordi det er en matematisk historie, men du kan få vinkelradianen med "Math.Atan2" -metoden ved at finde forskelsvektoren fra berøringspunkt 1 til berøringspunkt 2. Find forskellen mellem den opnåede vinkel og den tidligere erhvervede vinkel, og tilføj den til spritens rotationsvinkel.

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 - Tegning af sprites

Der er ingen større ændringer i tegning sprites. Det femte argument i SpriteBacth.Draw-metoden er indstillet til den beregnede rotationsvinkel.

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

Resumé af denne prøve

Denne gang forsøgte jeg at rotere sprite ved at knibe operation. Vi bruger ikke nogen nye klasser i særdeleshed, men jeg håber, du forstår, at vi kan realisere anvendt behandling baseret på de leverede funktioner.

Endeligt

Vi gennemgik eksempler og demonstrerede implementeringen af berøringsinteraktioner ved hjælp af Windows Phone 7 og XNA Game Studio 4.0. Indholdet omfattede single-touch og multi-touch touch erhvervelse og manipulation af berøringsinformation og behandling ved berøringsbevægelsesmanipulation ved hjælp af gestusspecifikke metoder.

Denne gang har jeg fokuseret på berøringspanelet, men der er stadig nogle funktioner, som jeg ikke har introduceret endnu. Windows Phone 7 indeholder også nye inputfunktioner i XNA Game Studio 4.0, f.eks. accelerometerindgang og stemmeinput. Der er nogle interessante funktioner, som jeg ikke kunne introducere denne gang, så nyd at udforske de funktioner, du vil bruge.