Tương tác cảm ứng trong phát triển trò chơi cho Windows Phone 7 Part 4 Pinch

Trang Cập Nhật :
Ngày tạo trang :

Chương trình! - 4.Pinch, kéo dài để chia tỷ lệ sprites

Về mẫu này

Điện thoại thông minh hiện đại, chẳng hạn như trình xem hình ảnh, cho phép bạn phóng to và thu nhỏ hình ảnh bằng cách sử dụng hai ngón tay để tăng hoặc thu nhỏ khoảng cách giữa các ngón tay của bạn. Bạn có thể thực hiện tương tự với Internet Explorer trên Windows Phone 7. Hành động này được gọi là "chụm, duỗi" trong Windows Phone 7.

Ngoài việc véo và kéo giãn, bạn cũng có thể sử dụng các hành động như "chạm" để chạm nhanh (chạm) một điểm trên màn hình và "vuốt" để nhanh chóng theo dõi màn hình. Những hành động này được gọi chung là cử chỉ.

Trong chương trình này, tôi muốn phóng to và giảm sprite hiển thị trên màn hình bằng thao tác chụm và kéo dài này. Ngoài ra, cho đến lần trước, tôi trực tiếp thu thập thông tin của bảng cảm ứng và xử lý nó, nhưng lần này tôi muốn xử lý các thao tác cảm ứng bằng các phương pháp dành riêng cho cử chỉ.

Mục tiêu của chương trình mẫu này

Chụm và kéo dài các hoạt động để phóng to và thu nhỏ sprite.

図 1 :ストレッチでスプライトを拡大
Hình 1: Kéo căng để phóng to sprite

Chương trình - Khai báo các trường

Không có lớp mới trong khai báo trường, nhưng nó có "tọa độ trung tâm của kết cấu", "độ phóng đại của sprite" và "khoảng cách giữa hai vị trí chạm cuối cùng khi chụm".

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

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

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

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

Chương trình - Bật cử chỉ

Lần này, chúng tôi sẽ thực hiện một quy trình chỉ có cử chỉ, nhưng ở trạng thái mặc định, không có cử chỉ nào có thể được sử dụng. Để truy xuất từng thông tin cử chỉ, bạn phải đặt cử chỉ được sử dụng cho thuộc tính TouchPanel.EnabledGestures.

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

Bật tất cả các cử chỉ sẽ ảnh hưởng đến hiệu suất, vì vậy hãy đảm bảo rằng bạn chỉ đặt các cử chỉ mà bạn muốn sử dụng. Ở đây, "GestureType.Pinch" được đặt để lấy thông tin thao tác pinch và "GestureType.PinchComplete" được đặt để cho biết rằng quá trình pinch đã hoàn tất. Vị trí cài đặt được đặt trong trình tạo Trò chơi.

Chương trình - Tải kết cấu

Tải kết cấu vẫn giống như trước đây, nhưng lần này chúng ta đang tính toán "tọa độ trung tâm của kết cấu". Điều này là do khi chia tỷ lệ sprite, nó chia tỷ lệ với tọa độ trung tâm là nguồn gốc.

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

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

Chương trình - Nhận thông tin cử chỉ

Chúng tôi nhận được thông tin cử chỉ (nhúm ở đây) trong phương thức Game.Update. Xử lý cử chỉ ở dạng lặp lại nhiều cử chỉ như bạn đã bật. Cấu trúc "TouchCollection" được sử dụng cho đến lần trước không được sử dụng.

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

Kiểm tra trạng thái của thuộc tính TouchPanel.IsGestureAvailable trong vòng lặp trong khi để biết thông tin cử chỉ và kiểm tra xem có thông tin cử chỉ sau không: Nếu bạn có thông tin cử chỉ sau, hãy sử dụng phương pháp "TouchPanel.ReadGesture" để lấy thông tin cử chỉ.

"GestureSample.GestureType" lưu trữ thông tin về loại cử chỉ nào được bao gồm, vì vậy hãy phân nhánh quy trình với một câu lệnh chuyển đổi dựa trên nó. Trong mẫu này, hàm xây dựng đặt enums "GestureType.Pinch" và "GestureType.PinchComplete" thành thuộc tính "TouchPanel.EnabledGestures", vì vậy chúng được phân nhánh tương ứng.

Chương trình - Xử lý cử chỉ nhúm

Sẽ nhanh hơn khi xem xét các nhận xét trong code cho những gì chúng ta đang làm, nhưng để tóm tắt những gì chúng ta đang làm, chúng ta tìm thấy sự khác biệt giữa khoảng cách giữa hai điểm tiếp xúc trước đó và khoảng cách điểm tiếp xúc giữa hai điểm lần này và sử dụng sự khác biệt đó để tăng hoặc giảm giá trị thang đo.

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;

Hai vị trí cảm ứng có thể có được với "GestureSample.Position" và "GestureSample.Position2", tương ứng. Bạn có thể trừ đi sự khác biệt giữa hai vectơ thu được và tìm khoảng cách giữa hai điểm bằng cách gọi phương thức "Vector2.Length".

Nhân tiện, ở đây chúng tôi xác định khoảng cách trước đó là 0 khi độ chụm không được thực hiện, vì vậy quá trình này được phân nhánh khi bắt đầu chèn ép và trong các vòng lặp thứ hai và tiếp theo. Điều này là do lần đầu tiên véo, không có khoảng cách trước đó, vì vậy không cần phải mở rộng quy mô.

Ngoài ra, lần này chúng tôi chỉ sử dụng hai thuộc tính, "GestureSample.Position" và "GestureSample.Position2", nhưng cũng có các thuộc tính "GestureSample.Delta" và "GestureSample.Delta2", có thể nhận được thông tin khác biệt từ vị trí chạm trước đó. Có hai thuộc tính mỗi thuộc tính, nhưng điều này dành cho cảm ứng đa điểm và đối với các cử chỉ sử dụng một lần chạm, bạn sẽ sử dụng các thuộc tính không có "2".

Chương trình - Xử lý khi cử chỉ chụm hoàn tất

Khi cử chỉ chụm hoàn tất (nhả một trong hai ngón tay khỏi bảng cảm ứng), khoảng cách giữa hai điểm trước được đặt trở lại thành 0. Ban đầu, có thể tốt hơn nếu sử dụng một lá cờ riêng biệt, nhưng vì về mặt vật lý không thể chạm vào cùng một vị trí bằng hai ngón tay, khoảng cách 0 được xác định là không véo. (Nếu độ phân giải thấp, có thể chạm vào cùng một vị trí ...)

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

Chương trình - Vẽ Sprites

Tôi sẽ không đi vào quá nhiều chi tiết ở đây vì nó chỉ là về việc vẽ sprite, nhưng tôi đã đặt sprite ở giữa màn hình và vẽ giá trị tỷ lệ được tính toán bằng cách phóng to và thu nhỏ nó với trung tâm của sprite làm nguồn gốc.

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

Tóm tắt mẫu này

Lần này, chúng tôi đã giải thích quy trình dành riêng cho cử chỉ. Trong mẫu, chúng tôi chỉ tạo một quá trình véo, nhưng cũng có "flicks" và "holds". Để tìm hiểu những cử chỉ nào có sẵn, hãy xem Trợ giúp XNA Game Studio 4.0 cho các enums GestureType.

Bạn có thể thực hiện điều tương tự từ thông tin cảm ứng thu được từ phương pháp TouchPanel.GetState mà không cần sử dụng các phương pháp hoặc cấu trúc cụ thể theo cử chỉ, nhưng trong trường hợp đó, bạn sẽ cần tự tính toán tốc độ quản lý ID đa chạm, thời gian chạm, nhấp nháy, v.v. Bằng cách sử dụng các phương pháp dành riêng cho cử chỉ, các triển khai này có thể được đơn giản hóa và cũng có lợi thế là tất cả các trò chơi và ứng dụng có thể được vận hành theo cùng một cách.

Khi bạn tự tạo quy trình bảng điều khiển cảm ứng, nếu bạn có thể thay thế quy trình tương tự bằng cử chỉ, chúng tôi khuyên bạn nên sử dụng quy trình này.

Chương trình! - 5.Pinch để xoay sprites

Về mẫu này

Độ chụm thường đề cập đến "chụm" và "kéo dài", nhưng quá trình chụm của XNA Game Studio 4.0 không giới hạn cụ thể quá trình ở hai điều đó, vì vậy bạn cũng có thể thực hiện các thao tác khoanh tròn một điểm tiếp xúc xung quanh một điểm tiếp xúc khác.

Ở đây, tôi muốn xoay sprite bằng phương thức hoạt động đó. Nhân tiện, lần này không có phương thức hoặc lớp mới nào xuất hiện và nó dựa trên tỷ lệ trước đó.

Trong phần mô tả mã mẫu trong bài viết này, các phần tương tự như mẫu chia tỷ lệ trước đó được bỏ qua.

Mục tiêu của chương trình mẫu này

Bằng cách xoay hai điểm tiếp xúc, sprite xoay. Hoạt động mở rộng quy mô trước đó cũng hoạt động.

図 2 :タッチポイントを回してスプライトを回転させています
Hình 2: Xoay sprite bằng cách xoay điểm tiếp xúc

Chương trình - Khai báo các trường

"Số lượng xoay sprite" và "Góc quay cuối cùng" được thêm vào chương trình chia tỷ lệ trước đó. Tất cả các góc được tính bằng radian.

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

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

Chương trình - Quy trình luân chuyển

Quá trình xoay được thực hiện trong các cử chỉ chụm theo cách tương tự như khi mở rộng quy mô.

Tôi sẽ không đi sâu vào quá nhiều chi tiết về việc tính toán xoay vì đó là một câu chuyện toán học, nhưng bạn có thể có được radian góc bằng phương pháp "Math.Atan2" bằng cách tìm vectơ chênh lệch từ điểm tiếp xúc 1 đến điểm chạm 2. Tìm sự khác biệt giữa góc thu được và góc thu được trước đó và thêm nó vào góc quay của 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;
}

Chương trình - Vẽ Sprites

Không có thay đổi lớn nào đối với việc vẽ sprites. Đối số thứ năm của phương pháp SpriteBacth.Draw được đặt thành góc quay được tính toán.

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

Tóm tắt mẫu này

Lần này, tôi đã cố gắng xoay sprite bằng thao tác véo. Chúng tôi không sử dụng bất kỳ lớp mới nào nói riêng, nhưng tôi hy vọng bạn hiểu rằng chúng tôi có thể nhận ra xử lý ứng dụng dựa trên các chức năng được cung cấp.

Cuối cùng

Chúng tôi đã xem qua các mẫu và chứng minh việc triển khai các tương tác cảm ứng bằng Windows Phone 7 và XNA Game Studio 4.0. Nội dung bao gồm thu thập cảm ứng một chạm và cảm ứng đa chạm và thao tác thông tin cảm ứng và xử lý bằng thao tác cử chỉ cảm ứng bằng các phương pháp dành riêng cho cử chỉ.

Lần này, tôi đã tập trung vào bảng điều khiển cảm ứng, nhưng vẫn còn một số chức năng mà tôi chưa giới thiệu. Windows Phone 7 cũng bao gồm các tính năng đầu vào mới trong XNA Game Studio 4.0, chẳng hạn như đầu vào gia tốc kế và nhập liệu bằng giọng nói. Có một số tính năng thú vị mà tôi không thể giới thiệu lần này, vì vậy hãy tận hưởng khám phá các chức năng bạn muốn sử dụng.