Interaksi sentuh dalam pengembangan game untuk Windows Phone 7 Bagian 4 Pinch

Halaman Diperbarui :
Tanggal pembuatan halaman :

Pemrograman! - 4.Cubit, peregangan hingga sprites skala

Tentang sampel ini

Smartphone modern, seperti penampil gambar, memungkinkan Anda memperbesar dan mengecilkan gambar dengan menggunakan dua jari untuk menambah atau mengecilkan jarak antara jari-jari Anda. Anda dapat melakukan hal yang sama dengan Internet Explorer di Windows Phone 7. Tindakan ini disebut "cubit, regangkan" di Windows Phone 7.

Selain mencubit dan meregangkan, Anda juga dapat menggunakan tindakan seperti "ketuk" untuk menyentuh sebentar (ketuk) satu titik di layar dan "jentikkan" untuk melacak layar dengan cepat. Tindakan ini secara kolektif disebut sebagai gerakan.

Dalam program ini, saya ingin memperbesar dan mengurangi sprite yang ditampilkan di layar dengan operasi cubitan dan peregangan ini. Juga, sampai terakhir kali, saya langsung memperoleh informasi dari panel sentuh dan memprosesnya, tetapi kali ini saya ingin menangani operasi sentuh menggunakan metode yang didedikasikan untuk gerakan.

Tujuan dari program sampel ini

Operasi cubit dan regangkan untuk memperbesar dan mengecilkan sprite.

図 1 :ストレッチでスプライトを拡大
Gambar 1: Regangkan untuk memperbesar sprite

Program - Mendeklarasikan Bidang

Tidak ada kelas baru dalam deklarasi bidang, tetapi memiliki "koordinat pusat tekstur", "pembesaran sprite", dan "jarak antara dua posisi sentuhan terakhir saat mencubit".

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

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

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

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

Program - Mengaktifkan Gerakan

Kali ini, kita akan melakukan proses hanya gerakan, tetapi dalam keadaan default, tidak ada gerakan yang dapat digunakan. Untuk mengambil setiap informasi gerakan, Anda harus mengatur gerakan yang akan digunakan untuk properti TouchPanel.EnabledGestures.

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

Mengaktifkan semua gerakan memengaruhi performa, jadi pastikan Anda hanya mengatur gerakan yang ingin Anda gunakan. Di sini, "GestureType.Pinch" diatur untuk mendapatkan informasi operasi cubitan dan "GestureType.PinchComplete" diatur untuk menunjukkan bahwa proses cubitan selesai. Lokasi pengaturan diatur dalam konstruktor Game.

Program - Memuat tekstur

Memuat tekstur sama seperti sebelumnya, tetapi kali ini kami menghitung "koordinat pusat tekstur". Ini karena ketika menskalakan sprite, skalanya dengan koordinat pusat sebagai asalnya.

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

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

Program - Dapatkan informasi gerakan

Kami mendapatkan informasi gerakan (cubit di sini) dalam metode Game.Update. Pemrosesan gerakan dalam bentuk mengulangi gerakan sebanyak yang telah Anda aktifkan. Struktur "TouchCollection" yang digunakan sampai terakhir kali tidak digunakan.

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

Periksa status properti TouchPanel.IsGestureAvailable di loop while untuk informasi gerakan dan periksa apakah informasi gerakan berikut ada: Jika Anda memiliki informasi gerakan berikut, gunakan metode "TouchPanel.ReadGesture" untuk mendapatkan informasi gerakan.

"GestureSample.GestureType" menyimpan informasi tentang jenis gerakan mana yang disertakan, jadi cabangkan proses dengan pernyataan sakelar berdasarkan itu. Dalam sampel ini, konstruktor menetapkan enum "GestureType.Pinch" dan "GestureType.PinchComplete" ke properti "TouchPanel.EnabledGestures", sehingga masing-masing bercabang.

Program - Penanganan gerakan mencubit

Lebih cepat untuk melihat komentar dalam kode untuk apa yang kita lakukan, tetapi untuk meringkas apa yang kita lakukan, kita menemukan perbedaan antara jarak antara dua titik kontak sebelumnya dan jarak titik kontak antara dua titik kali ini, dan menggunakan perbedaan itu untuk menambah atau mengurangi nilai skala.

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;

Dua posisi sentuh dapat diperoleh dengan "GestureSample.Position" dan "GestureSample.Position2", masing-masing. Anda dapat mengurangi perbedaan antara dua vektor yang diperoleh dan menemukan jarak antara dua titik dengan memanggil metode "Vector2.Length".

Ngomong-ngomong, di sini kita mendefinisikan jarak sebelumnya sebagai 0 ketika mencubit tidak dilakukan, sehingga prosesnya bercabang ketika mencubit dimulai dan pada loop kedua dan selanjutnya. Ini karena pertama kali mencubit, tidak ada jarak sebelumnya, jadi tidak perlu menskalakan.

Juga, kali ini kita hanya menggunakan dua properti, "GestureSample.Position" dan "GestureSample.Position2", tetapi ada juga properti "GestureSample.Delta" dan "GestureSample.Delta2", yang bisa mendapatkan informasi perbedaan dari posisi sentuh sebelumnya. Ada dua properti masing-masing, tetapi ini untuk multi-sentuhan, dan untuk gerakan yang hanya menggunakan satu sentuhan, Anda akan menggunakan properti tanpa "2".

Program - Penanganan saat gerakan mencubit selesai

Ketika gerakan mencubit selesai (melepaskan salah satu jari dari panel sentuh), jarak antara dua titik sebelumnya diatur kembali ke 0. Awalnya, mungkin lebih baik menggunakan bendera terpisah, tetapi karena secara fisik tidak mungkin untuk menyentuh posisi yang sama dengan dua jari, jarak 0 didefinisikan sebagai tidak mencubit. (Jika resolusinya rendah, dimungkinkan untuk menyentuh posisi yang sama ...)

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

Program - Menggambar Sprite

Saya tidak akan membahas terlalu banyak detail di sini karena ini hanya tentang menggambar sprite, tetapi saya menempatkan sprite di tengah layar dan menggambar nilai skala yang dihitung dengan memperbesar dan mengecilkannya dengan pusat sprite sebagai asalnya.

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

Ringkasan sampel ini

Kali ini, kami menjelaskan proses yang didedikasikan untuk gerakan. Dalam sampel, kami hanya membuat proses cubitan, tetapi ada juga "jentikan" dan "pegangan". Untuk mengetahui gerakan apa yang tersedia, lihat XNA Game Studio 4.0 Bantuan untuk enum GestureType.

Anda dapat menerapkan hal yang sama dari informasi sentuh yang diperoleh dari metode TouchPanel.GetState tanpa menggunakan metode atau struktur khusus gerakan, tetapi dalam hal ini, Anda perlu menghitung sendiri kecepatan manajemen ID multi-sentuh, waktu sentuh, jentikan, dll. Dengan menggunakan metode khusus gerakan, implementasi ini dapat disederhanakan, dan ada juga keuntungan bahwa semua game dan aplikasi dapat dioperasikan dengan cara yang sama.

Saat Anda membuat proses panel sentuh sendiri, jika Anda dapat mengganti proses serupa sebagai gerakan, kami sarankan Anda menggunakan ini.

Pemrograman! - 5.Cubit untuk memutar sprite

Tentang sampel ini

Mencubit biasanya mengacu pada "mencubit" dan "meregangkan", tetapi proses cubitan XNA Game Studio 4.0 tidak secara khusus membatasi proses pada keduanya, jadi Anda juga dapat melakukan operasi yang melingkari satu titik kontak di sekitar titik kontak lainnya.

Di sini, saya ingin memutar sprite dengan metode operasi itu. Ngomong-ngomong, tidak ada metode atau kelas baru yang muncul kali ini, dan ini didasarkan pada penskalaan sebelumnya.

Dalam deskripsi kode sampel dalam artikel ini, bagian yang sama dengan sampel penskalaan sebelumnya dihilangkan.

Tujuan dari program sampel ini

Dengan memutar dua titik kontak, sprite berputar. Operasi penskalaan sebelumnya juga berfungsi.

図 2 :タッチポイントを回してスプライトを回転させています
Gambar 2: Memutar sprite dengan memutar touchpoint

Program - Mendeklarasikan Bidang

"Jumlah rotasi sprite" dan "Sudut rotasi terakhir" ditambahkan ke program penskalaan sebelumnya. Semua sudut dihitung dalam radian.

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

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

Program - Proses Rotasi

Proses rotasi dilakukan selama gerakan mencubit dengan cara yang sama seperti saat penskalaan.

Saya tidak akan membahas terlalu banyak detail tentang menghitung rotasi karena ini adalah cerita matematika, tetapi Anda bisa mendapatkan radian sudut dengan metode "Math.Atan2" dengan menemukan vektor perbedaan dari touchpoint 1 ke touchpoint 2. Temukan perbedaan antara sudut yang diperoleh dan sudut yang diperoleh sebelumnya dan tambahkan ke sudut rotasi sprite.

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 - Menggambar Sprite

Tidak ada perubahan besar pada menggambar sprite. Argumen kelima dari metode SpriteBacth.Draw diatur ke sudut rotasi yang dihitung.

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

Ringkasan sampel ini

Kali ini, saya mencoba memutar sprite dengan operasi cubitan. Kami tidak menggunakan kelas baru secara khusus, tetapi saya harap Anda memahami bahwa kami dapat mewujudkan pemrosesan terapan berdasarkan fungsi yang disediakan.

Akhirnya

Kami berjalan melalui sampel dan mendemonstrasikan implementasi interaksi sentuh menggunakan Windows Phone 7 dan XNA Game Studio 4.0. Konten termasuk akuisisi sentuhan tunggal dan multi-sentuhan sentuh dan manipulasi informasi sentuhan, dan pemrosesan dengan manipulasi gerakan sentuh menggunakan metode khusus gerakan.

Kali ini, saya telah fokus pada panel sentuh, tetapi masih ada beberapa fungsi yang belum saya perkenalkan. Windows Phone 7 juga menyertakan fitur input baru di XNA Game Studio 4.0, seperti input akselerometer dan input suara. Ada beberapa fitur menarik yang tidak dapat saya perkenalkan kali ini, jadi silakan nikmati menjelajahi fungsi yang ingin Anda gunakan.