Sentuh interaksi dalam pembangunan permainan untuk Windows Phone 7 Bahagian 4 Pinch
Pengaturcaraan! - 4.Pinch, renggang ke skala sprites
Mengenai sampel ini
Telefon pintar moden, seperti penonton imej, membolehkan anda membesarkan dan mengecilkan imej dengan menggunakan dua jari untuk meningkatkan atau mengecilkan jarak antara jari anda. Anda boleh melakukan perkara yang sama dengan Internet Explorer pada Windows Phone 7. Tindakan ini dipanggil "cubit, regangan" dalam Windows Phone 7.
Selain mencubit dan regangan, anda juga boleh menggunakan tindakan seperti "ketik" untuk menyentuh secara ringkas (ketik) satu titik pada skrin dan "kuis" untuk mengesan skrin dengan cepat. Tindakan ini secara kolektif dirujuk sebagai gerak isyarat.
Dalam program ini, saya ingin membesarkan dan mengurangkan sprite yang dipaparkan pada skrin dengan operasi mencubit dan regangan ini. Juga, sehingga kali terakhir, saya secara langsung memperoleh maklumat panel sentuh dan memprosesnya, tetapi kali ini saya ingin mengendalikan operasi sentuhan menggunakan kaedah yang dikhaskan untuk gerak isyarat.
Matlamat program sampel ini
Mencubit dan meregangkan operasi untuk membesarkan dan mengecutkan sprite.
Rajah 1: Regangkan untuk membesarkan sprite
Program - Mengisytiharkan Bidang
Tidak ada kelas baru dalam pengisytiharan lapangan, tetapi ia mempunyai "koordinat tengah tekstur", "pembesaran sprite", dan "jarak antara dua kedudukan sentuhan terakhir apabila mencubit".
<summary>
テクスチャー
</summary>
Texture2D texture;
<summary>
テクスチャーの中心座標
</summary>
Vector2 textureCenterPos;
<summary>
スプライトのスケール
</summary>
float scale = 1;
<summary>
前回の 2 点間の距離
</summary>
float previousLength = 0;
Program - Membolehkan Gerak Isyarat
Kali ini, kami akan melakukan proses gerak isyarat sahaja, tetapi dalam keadaan lalai, tiada gerak isyarat boleh digunakan. Untuk mendapatkan semula setiap maklumat gerak isyarat, anda mesti mengesetkan gerak isyarat untuk digunakan bagi sifat TouchPanel.EnabledGestures.
// タッチパネルでピンチのジェスチャーを有効にする
TouchPanel.EnabledGestures = GestureType.Pinch | GestureType.PinchComplete;
Mendayakan semua gerak isyarat menjejaskan prestasi, jadi pastikan anda hanya mengesetkan gerak isyarat yang anda mahu gunakan. Di sini, "GestureType.Pinch" ditetapkan untuk mendapatkan maklumat operasi cubit dan "GestureType.PinchComplete" ditetapkan untuk menunjukkan bahawa proses cubit selesai. Lokasi tetapan ditetapkan dalam pembina Permainan.
Program - Memuatkan tekstur
Memuatkan tekstur adalah sama seperti sebelumnya, tetapi kali ini kita mengira "koordinat tengah tekstur". Ini kerana apabila menskalakan sprite, ia skala dengan koordinat pusat sebagai asal.
// テクスチャーをコンテンツパイプラインから読み込む
texture = Content.Load<Texture2D>("Texture");
// テクスチャーの中心座標を求める
textureCenterPos = new Vector2(texture.Width / 2, texture.Height / 2);
Program - Dapatkan maklumat gerak isyarat
Kami mendapat maklumat gerak isyarat (cubit di sini) dalam kaedah Game.Update. Pemprosesan gerak isyarat adalah dalam bentuk mengulangi seberapa banyak gerak isyarat yang anda telah dayakan. Struktur "TouchCollection" yang digunakan sehingga kali terakhir tidak digunakan.
// 次のジェスチャー情報が取得できる場合は true を返し続けます
while (TouchPanel.IsGestureAvailable)
{
// 次のジェスチャー情報を読み込みます
GestureSample gs = TouchPanel.ReadGesture();
switch (gs.GestureType)
{
case GestureType.Pinch:
// ここにピンチ処理を記述します
break;
case GestureType.PinchComplete:
// ここにピンチ完了処理を記述します
break;
}
}
Semak keadaan sifat TouchPanel.IsGestureAvailable dalam gelung sementara untuk maklumat gerak isyarat dan semak sama ada maklumat gerak isyarat berikut hadir: Jika anda mempunyai maklumat gerak isyarat berikut, gunakan kaedah "TouchPanel.ReadGesture" untuk mendapatkan maklumat gerak isyarat.
"GestureSample.GestureType" menyimpan maklumat tentang jenis gerak isyarat yang disertakan, jadi cawangan proses dengan pernyataan suis berdasarkannya. Dalam sampel ini, pembina menetapkan "GestureType.Pinch" dan "GestureType.PinchComplete" enums kepada harta "TouchPanel.EnabledGestures", jadi ia bercabang masing-masing.
Program - Pengendalian gerak isyarat cubit
Lebih pantas untuk melihat komen dalam kod untuk apa yang kami lakukan, tetapi untuk meringkaskan apa yang kami lakukan, kami mendapati perbezaan antara jarak antara dua titik sentuh sebelumnya dan jarak titik sentuh antara dua titik kali ini, dan menggunakan perbezaan itu untuk meningkatkan atau mengurangkan 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;
Kedua-dua kedudukan sentuhan boleh didapati dengan "GestureSample.Position" dan "GestureSample.Position2", masing-masing. Anda boleh menolak perbezaan antara kedua-dua vektor yang diperolehi dan mencari jarak antara dua titik dengan memanggil kaedah "Vector2.Length".
Dengan cara ini, di sini kita menentukan jarak sebelumnya sebagai 0 apabila mencubit tidak dilakukan, jadi proses itu bercabang apabila mencubit dimulakan dan dalam gelung kedua dan seterusnya. Ini kerana kali pertama mencubit, tidak ada jarak sebelumnya, jadi tidak perlu skala.
Juga, kali ini kita menggunakan hanya dua sifat, "GestureSample.Position" dan "GestureSample.Position2", tetapi terdapat juga sifat "GestureSample.Delta" dan "GestureSample.Delta2", yang boleh mendapatkan maklumat perbezaan daripada kedudukan sentuhan sebelumnya. Terdapat dua sifat masing-masing, tetapi ini adalah untuk berbilang sentuhan, dan untuk gerak isyarat yang hanya menggunakan sentuhan tunggal, anda akan menggunakan sifat tanpa "2".
Program - Pengendalian apabila isyarat cubit selesai
Apabila isyarat cubit selesai (melepaskan salah satu jari dari panel sentuh), jarak antara dua titik sebelumnya ditetapkan kembali ke 0. Pada asalnya, mungkin lebih baik menggunakan bendera yang berasingan, tetapi kerana secara fizikal mustahil untuk menyentuh kedudukan yang sama dengan dua jari, jarak 0 ditakrifkan sebagai tidak mencubit. (Jika resolusi rendah, mungkin untuk menyentuh kedudukan yang sama ...)
case GestureType.PinchComplete:
// ピンチが終了した場合は保持している距離を 0 に戻して
// 完了したことにします
previousLength = 0;
break;
Program - Lukisan Sprites
Saya tidak akan terlalu terperinci di sini kerana ia hanya mengenai melukis sprite, tetapi saya meletakkan sprite di tengah skrin dan menarik nilai skala yang dikira dengan membesarkan dan mengecilkannya dengan pusat sprite sebagai asal.
// スプライトの描画準備
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 menerangkan proses yang dikhaskan untuk gerak isyarat. Dalam sampel, kami hanya membuat proses cubit, tetapi terdapat juga "kelipan" dan "pegangan". Untuk mengetahui gerak isyarat yang tersedia, lihat Bantuan XNA Game Studio 4.0 untuk enum GestureType.
Anda boleh melaksanakan perkara yang sama dari maklumat sentuhan yang diperoleh daripada kaedah TouchPanel.GetState tanpa menggunakan kaedah atau struktur khusus gerak isyarat, tetapi dalam kes itu, anda perlu mengira kelajuan pengurusan ID berbilang sentuhan, masa sentuhan, kelipan, dll. Dengan menggunakan kaedah khusus isyarat, pelaksanaan ini dapat dipermudahkan, dan terdapat juga kelebihan bahawa semua permainan dan aplikasi dapat dikendalikan dengan cara yang sama.
Apabila anda membuat proses panel sentuh sendiri, jika anda boleh menggantikan proses yang sama sebagai gerak isyarat, kami mengesyorkan agar anda menggunakan ini.
Pengaturcaraan! - 5.Pinch untuk berputar sprites
Mengenai sampel ini
Mencubit biasanya merujuk kepada "mencubit" dan "regangan", tetapi proses cubit XNA Game Studio 4.0 tidak mengehadkan proses secara khusus kepada kedua-duanya, jadi anda juga boleh melakukan operasi yang mengelilingi satu titik sentuh di sekitar titik sentuh lain.
Di sini, saya ingin memutarkan sprite dengan kaedah operasi itu. Dengan cara ini, tiada kaedah atau kelas baru muncul kali ini, dan ia berdasarkan penskalaan sebelumnya.
Dalam perihalan kod sampel dalam artikel ini, bahagian yang sama seperti sampel penskalaan sebelumnya dikeluarkan.
Matlamat program sampel ini
Dengan memutarkan dua titik sentuh, sprite berputar. Operasi penskalaan sebelumnya juga berfungsi.
Rajah 2: Memutarkan sprite dengan mengubah titik sentuh
Program - Mengisytiharkan Bidang
"Jumlah putaran sprite" dan "Sudut putaran terakhir" ditambah kepada program penskalaan sebelumnya. Semua sudut dikira dalam radian.
<summary>
スプライトの回転量(radian)
</summary>
float rotate;
<summary>
前回の回転角度(radian)
</summary>
float previousAngle;
Program - Proses Penggiliran
Proses putaran dilakukan semasa gerak isyarat cubit dengan cara yang sama seperti semasa penskalaan.
Saya tidak akan terlalu terperinci tentang mengira putaran kerana ia adalah cerita matematik, tetapi anda boleh mendapatkan radian sudut dengan kaedah "Math.Atan2" dengan mencari vektor perbezaan dari titik sentuh 1 hingga titik sentuh 2. Cari perbezaan antara sudut yang diperolehi dan sudut yang diperoleh sebelum ini dan tambahkannya pada sudut putaran 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 - Lukisan Sprites
Tiada perubahan besar untuk melukis sprites. Argumen kelima kaedah SpriteBacth.Draw ditetapkan kepada sudut putaran yang dikira.
// スプライトの描画準備
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 cuba memutarkan sprite dengan operasi cubit. Kami tidak menggunakan mana-mana kelas baru khususnya, tetapi saya harap anda memahami bahawa kami dapat merealisasikan pemprosesan yang diterapkan berdasarkan fungsi yang disediakan.
Akhirnya
Kami berjalan melalui sampel dan menunjukkan pelaksanaan interaksi sentuhan menggunakan Windows Phone 7 dan XNA Game Studio 4.0. Kandungan tersebut termasuk pemerolehan sentuhan tunggal dan berbilang sentuhan dan manipulasi maklumat sentuhan, dan pemprosesan manipulasi gerak isyarat sentuhan menggunakan kaedah khusus gerak isyarat.
Kali ini, saya telah memberi tumpuan kepada panel sentuh, tetapi masih ada beberapa fungsi yang belum saya perkenalkan. Windows Phone 7 juga menyertakan ciri input baharu dalam XNA Game Studio 4.0, seperti input pecutan dan input suara. Terdapat beberapa ciri menarik yang tidak dapat saya perkenalkan kali ini, jadi sila nikmati meneroka fungsi yang ingin anda gunakan.