Skārienu mijiedarbība spēļu izstrādē operētājsistēmai Windows Phone 7 4. daļa Saspiešana

Lapa atjaunota :
Lapas izveides datums :

Programmēšanas! - 4.Saspiediet, izstiepiet, lai mērogotu sprites

Par šo paraugu

Mūsdienu viedtālruņi, piemēram, attēlu skatītāji, ļauj palielināt un samazināt attēlu, izmantojot divus pirkstus, lai palielinātu vai samazinātu attālumu starp pirkstiem. To pašu var izdarīt ar Internet Explorer operētājsistēmā Windows Phone 7. Operētājsistēmā Windows Phone 7 šo darbību sauc par "savilkšanu, izstiepšanu".

Papildus saspiešanai un izstiepšanai varat izmantot arī tādas darbības kā "pieskarieties", lai īsi pieskartos (pieskartos) vienam punktam ekrānā un "švīkošanai", lai ātri izsekotu ekrānam. Šīs darbības kopā sauc par žestiem.

Šajā programmā es vēlētos palielināt un samazināt ekrānā redzamo sprite ar šo saspiešanas un stiepšanās darbību. Arī līdz pēdējai reizei es tieši ieguvu skārienjutīgā paneļa informāciju un apstrādāju to, bet šoreiz es vēlētos rīkoties ar skārienjutīgām operācijām, izmantojot metodes, kas veltītas žestiem.

Šīs izlases programmas mērķi

Saspiediet un izstiepiet darbības, lai palielinātu un samazinātu sprite.

図 1 :ストレッチでスプライトを拡大
1. attēls: Izstiepiet, lai palielinātu sprite

Programma — lauku deklarēšana

Lauka deklarācijā nav jaunas klases, bet tai ir "tekstūras centrālā koordināta", "sprite palielinājums" un "attālums starp pēdējām divām pieskāriena pozīcijām, saspiežot".

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

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

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

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

Programma - žestu iespējošana

Šoreiz mēs veiksim tikai žestu procesu, taču noklusējuma stāvoklī nevienu no žestiem nevar izmantot. Lai izgūtu katra žesta informāciju, ir jāiestata žests, kas jāizmanto rekvizītam TouchPanel.EnabledGestures.

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

Visu žestu iespējošana ietekmē veiktspēju, tāpēc noteikti iestatiet tikai tos žestus, kurus vēlaties izmantot. Šeit "GestureType.Pinch" ir iestatīts, lai iegūtu informāciju par saspiešanas darbību, un "GestureType.PinchComplete" ir iestatīts, lai norādītu, ka saspiešanas process ir pabeigts. Iestatījuma atrašanās vieta ir iestatīta spēles konstruktorā.

Programma - tekstūru iekraušana

Iekraušanas tekstūras ir tādas pašas kā iepriekš, bet šoreiz mēs aprēķinām "tekstūras centra koordinātu". Tas ir tāpēc, ka, mērogojot sprite, tas mērogo ar centrālo koordinātu kā izcelsmi.

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

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

Programma - iegūstiet žestu informāciju

Mēs saņemam žestu informāciju (saspiediet šeit) Game.Update metodē. Žestu apstrāde izpaužas kā tik žestu atkārtošana, cik esat iespējojis. "TouchCollection" struktūra, kas tika izmantota līdz pēdējai reizei, netiek izmantota.

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

Pārbaudiet rekvizīta TouchPanel.IsGestureAvailable stāvokli cilpas laikā, lai iegūtu žestu informāciju, un pārbaudiet, vai ir pieejama šāda žestu informācija: Ja jums ir šāda informācija par žestu, izmantojiet metodi "TouchPanel.ReadGesture", lai iegūtu informāciju par žestu.

"GestureSample.GestureType" saglabā informāciju par to, kurš žesta veids ir iekļauts, tāpēc sazarojiet procesu ar slēdža priekšrakstu, pamatojoties uz to. Šajā paraugā konstruktors iestata "GestureType.Pinch" un "GestureType.PinchComplete" enums rekvizītam "TouchPanel.EnabledGestures", tāpēc tie ir attiecīgi sazaroti.

Programma - Saspiešanas žestu apstrāde

Ātrāk ir aplūkot komentārus kodā par to, ko mēs darām, bet, apkopojot to, ko mēs darām, mēs atrodam atšķirību starp attālumu starp iepriekšējiem diviem saskares punktiem un saskares punkta attālumu starp abiem punktiem šoreiz un izmantojam šo starpību, lai palielinātu vai samazinātu skalas vērtību.

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;

Abas pieskāriena pozīcijas var iegūt, attiecīgi izmantojot "GestureSample.Position" un "GestureSample.Position2". Jūs varat atņemt starpību starp diviem iegūtajiem vektoriem un atrast attālumu starp abiem punktiem, izsaucot metodi "Vector2.Length".

Starp citu, šeit mēs definējam iepriekšējo attālumu kā 0, kad saspiešana netiek veikta, tāpēc process tiek sazarots, kad tiek sākta saspiešana un otrajā un turpmākajās cilpās. Tas ir tāpēc, ka, pirmo reizi saspiežot, nav iepriekšēja attāluma, tāpēc nav nepieciešams mērogot.

Arī šoreiz mēs izmantojam tikai divus rekvizītus, "GestureSample.Position" un "GestureSample.Position2", bet ir arī rekvizīti "GestureSample.Delta" un "GestureSample.Delta2", kas var iegūt atšķirību informāciju no iepriekšējās skārienjutīgās pozīcijas. Katrā ir divas īpašības, bet tas ir paredzēts daudzskārienu, un žestiem, kas izmanto tikai vienu pieskārienu, jūs izmantosit rekvizītus bez "2".

Programma - Apiešanās, kad saspiešanas žests ir pabeigts

Kad saspiešanas žests ir pabeigts (atbrīvojot jebkuru pirkstu no skārienpaneļa), attālums starp iepriekšējiem diviem punktiem tiek iestatīts atpakaļ uz 0. Sākotnēji var būt labāk izmantot atsevišķu karodziņu, bet, tā kā fiziski nav iespējams pieskarties vienai un tai pašai pozīcijai ar diviem pirkstiem, attālums 0 tiek definēts kā nesaspiežams. (Ja izšķirtspēja ir zema, var būt iespējams pieskarties tai pašai pozīcijai ...)

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

Programma - Sprites zīmēšana

Es šeit neiedziļināšos pārāk daudz detaļās, jo runa ir tikai par sprite zīmēšanu, bet es novietoju sprite ekrāna centrā un uzzīmēju aprēķināto skalas vērtību, palielinot un sašaurinot to ar sprite centru kā izcelsmi.

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

Šī parauga kopsavilkums

Šoreiz mēs izskaidrojām procesu, kas veltīts žestiem. Paraugā mēs izveidojam tikai šķipsnu procesu, bet ir arī "flicks" un "hold". Lai uzzinātu, kādi žesti ir pieejami, skatiet XNA Game Studio 4.0 palīdzību par GestureType enums.

To pašu varat īstenot no skārienjutīgās informācijas, kas iegūta no TouchPanel.GetState metodes, neizmantojot žestiem specifiskas metodes vai struktūras, taču tādā gadījumā jums pašam būs jāaprēķina daudzskārienu ID pārvaldības ātrums, pieskāriena laiks, flicks utt. Izmantojot žestiem specifiskas metodes, šīs ieviešanas var vienkāršot, un ir arī priekšrocība, ka visas spēles un lietojumprogrammas var darbināt vienādi.

Ja pats izveidojat skārienpaneļa procesu, ja līdzīgu procesu varat aizstāt ar žestu, iesakām to izmantot.

Programmēšanas! - 5.Saspiediet, lai pagrieztu sprites

Par šo paraugu

Saspiešana parasti attiecas uz "saspiešanu" un "stiepšanos", taču XNA Game Studio 4.0 saspiešanas process īpaši neierobežo procesu ar šiem diviem, tāpēc varat arī veikt darbības, kas apliec vienu pieskāriena punktu ap citu saskares punktu.

Šeit es gribētu pagriezt sprite ar šo darbības metodi. Starp citu, šoreiz neparādījās jaunas metodes vai klases, un tas ir balstīts uz iepriekšējo mērogošanu.

Šajā rakstā sniegtajā parauga koda aprakstā ir izlaistas tās pašas daļas, kas iepriekšējā mērogošanas paraugā.

Šīs izlases programmas mērķi

Pagriežot abus saskares punktus, sprite griežas. Darbojas arī iepriekšējā mērogošanas operācija.

図 2 :タッチポイントを回してスプライトを回転させています
2. attēls: Sprite pagriešana, pagriežot saskares punktu

Programma — lauku deklarēšana

"Sprite rotācijas summa" un "Pēdējais rotācijas leņķis" tiek pievienoti iepriekšējai mērogošanas programmai. Visi leņķi tiek aprēķināti radiānos.

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

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

Programma - rotācijas process

Rotācijas process tiek veikts saspiešanas žestu laikā tāpat kā mērogojot.

Es neiedziļināšos pārāk detalizēti par rotācijas aprēķināšanu, jo tas ir matemātikas stāsts, bet jūs varat iegūt leņķa radiānu ar metodi "Math.Atan2", atrodot starpības vektoru no saskares punkta 1 līdz 2. pieskāriena punktam. Atrodiet atšķirību starp iegūto leņķi un iepriekš iegūto leņķi un pievienojiet to sprite rotācijas leņķim.

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

Programma - Sprites zīmēšana

Sprites zīmēšanā nav būtisku izmaiņu. SpriteBacth.Draw metodes piektais arguments ir iestatīts uz aprēķināto rotācijas leņķi.

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

Šī parauga kopsavilkums

Šoreiz es mēģināju pagriezt sprite ar saspiešanas darbību. Mēs īpaši neizmantojam jaunas klases, bet es ceru, ka jūs saprotat, ka mēs varam realizēt lietišķo apstrādi, pamatojoties uz sniegtajām funkcijām.

Beidzot

Mēs izstaigājām paraugus un demonstrējām skārienu mijiedarbības ieviešanu, izmantojot Windows Phone 7 un XNA Game Studio 4.0. Saturs ietvēra vienskāriena un daudzskārienu iegūšanu un manipulācijas ar skārieninformāciju, kā arī apstrādi ar skārienžestu manipulācijām, izmantojot žestiem raksturīgas metodes.

Šoreiz esmu koncentrējies uz skārienjutīgo paneli, bet joprojām ir dažas funkcijas, kuras vēl neesmu ieviesis. Operētājsistēmā Windows Phone 7 ir iekļauti arī jauni XNA Game Studio 4.0 ievades līdzekļi, piemēram, akselerometra ievade un balss ievade. Ir dažas interesantas funkcijas, kuras es šoreiz nevarēju ieviest, tāpēc, lūdzu, izbaudiet to funkciju izpēti, kuras vēlaties izmantot.