אינטראקציות מגע בפיתוח משחקים עבור Windows Phone 7 Part 4 צביטה

עודכן דף :
תאריך יצירת דף :

תכנות! - 4.צביטה, מתיחה לקנה מידה של שדונים

אודות מדגם זה

טלפונים חכמים מודרניים, כגון מציגי תמונות, מאפשרים לך להגדיל ולכווץ תמונה באמצעות שתי אצבעות כדי להגדיל או לכווץ את המרחק בין האצבעות. באפשרותך לעשות את אותו הדבר עם אינטרנט אקספלורר ב- Windows Phone 7. פעולה זו נקראת "צביטה, מתיחה" ב- Windows Phone 7.

בנוסף לצביטה ומתיחה, באפשרותך גם להשתמש בפעולות כגון "הקש" כדי לגעת בקצרה (להקיש) בנקודה אחת על המסך ו"להקיש " כדי לעקוב במהירות אחר המסך. פעולות אלה מכונות באופן קולקטיבי מחוות.

בתוכנית זו, אני רוצה להגדיל ולהפחית את ספרייט המוצג על המסך על ידי פעולה זו צביטה ומתיחה. כמו כן, עד הפעם האחרונה, השגתי ישירות את המידע של לוח המגע ועיבדתי אותו, אך הפעם ברצוני לטפל בפעולות מגע בשיטות המוקדשות למחוות.

מטרות התוכנית לדוגמה

פעולות צביטה ומתיחה להגדלה וכיווץ של הספרייט.

図 1 :ストレッチでスプライトを拡大
איור 1: מתיחה להגדלת הספרייט

תכנית - הכרזה על שדות

אין מחלקה חדשה בהצהרת השדה, אך יש לה "את הקואורדינטות המרכזיות של המרקם", "ההגדלה של הספרייט", ו"המרחק בין שתי עמדות המגע האחרונות בעת צביטה".

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

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

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

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

תוכנית - הפעלת מחוות

הפעם, נבצע תהליך של מחווה בלבד, אך במצב ברירת המחדל, לא ניתן להשתמש באף אחת מהמחוות. כדי לאחזר כל מידע על מחווה, עליך להגדיר את המחווה לשימוש עבור המאפיין TouchPanel.EnabledGestures.

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

הפיכת כל המחוות לזמינות משפיעה על הביצועים, לכן הקפד להגדיר רק את המחוות שבהן ברצונך להשתמש. כאן, "GestureType.Pinch" מוגדר לקבל מידע על פעולת הצביטה ו-"GestureType.PinchComplete" מוגדר כדי לציין שתהליך הצביטה הושלם. מיקום ההגדרה מוגדר בבנאי המשחק.

תוכנית - טעינת טקסטורות

טעינת טקסטורות זהה לקודמתה, אך הפעם אנו מחשבים את "קואורדינטת המרכז של המרקם". הסיבה לכך היא שכאשר משנים קנה מידה של ספרייט, הוא מתרחב עם הקואורדינטות המרכזיות כמקור.

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

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

תוכנית - קבל מידע על מחוות

אנו מקבלים מידע על מחוות (צבוט כאן) בפעולת השירות Game.Update. עיבוד מחוות הוא בצורה של חזרה על כמה מחוות שהפעלת. מבנה "TouchCollection" שהיה בשימוש עד הפעם האחרונה אינו בשימוש.

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

בדוק את המצב של המאפיין TouchPanel.IsGestureAvailable בלולאת הזמן לקבלת מידע על מחוות ובדוק אם פרטי המחוות הבאים קיימים: אם יש לך את פרטי המחוות הבאים, השתמש בשיטה "TouchPanel.ReadGesture" כדי לקבל את פרטי המחווה.

"GestureSample.GestureType" מאחסן מידע אודות סוג המחווה הכלול, ולכן הסתעף התהליך במשפט מתג המבוסס עליו. בדוגמה זו, הבנאי מגדיר את הפונקציות "GestureType.Pinch" ו-"GestureType.PinchComplete" למאפיין "TouchPanel.EnabledGestures", כך שהן מסועפות בהתאמה.

תוכנית - טיפול במחוות צביטה

מהר יותר להסתכל על ההערות בקוד עבור מה שאנחנו עושים, אבל כדי לסכם את מה שאנחנו עושים, אנחנו מוצאים את ההבדל בין המרחק בין שתי נקודות המגע הקודמות לבין מרחק נקודת המגע בין שתי הנקודות הפעם, ומשתמשים בהפרש הזה כדי להגדיל או להקטין את ערך קנה המידה.

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;

ניתן להשיג את שני מיקומי המגע באמצעות "GestureSample.Position" ו-"GestureSample.Position2", בהתאמה. ניתן להחסיר את ההפרש בין שני הווקטורים המתקבלים ולמצוא את המרחק בין שתי הנקודות על ידי קריאה לשיטת "Vector2.Length".

אגב, כאן אנו מגדירים את המרחק הקודם כ -0 כאשר צביטה אינה מבוצעת, ולכן התהליך מסועף כאשר צביטה מתחילה ובלולאות השנייה והבאה. הסיבה לכך היא שבפעם הראשונה של צביטה, אין מרחק קודם, ולכן אין צורך בקנה מידה.

כמו כן, הפעם אנו משתמשים רק בשני מאפיינים, "GestureSample.Position" ו- "GestureSample.Position2", אך ישנם גם מאפיינים "GestureSample.Delta" ו- "GestureSample.Delta2", שיכולים לקבל את מידע ההבדל ממיקום המגע הקודם. ישנם שני מאפיינים כל אחד, אבל זה עבור רב מגע, ועל מחוות המשתמשות רק בנגיעה אחת, תשתמש במאפיינים ללא "2".

תוכנית - טיפול בסיום מחוות הצביטה

לאחר השלמת מחוות הצביטה (שחרור אחת האצבעות מלוח המגע), המרחק בין שתי הנקודות הקודמות מוגדר בחזרה ל- 0. במקור, ייתכן שעדיף להשתמש בדגל נפרד, אך מכיוון שאי אפשר פיזית לגעת באותה תנוחה בשתי אצבעות, המרחק של 0 מוגדר כלא צובט. (אם הרזולוציה נמוכה, ייתכן שניתן יהיה לגעת באותה תנוחה ...)

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

תוכנית - ציור שדונים

אני לא אכנס כאן ליותר מדי פרטים כי זה רק על ציור הספרייט, אבל הנחתי את הספרייט במרכז המסך וציירתי את ערך קנה המידה המחושב על ידי הגדלה וכיווץ שלו עם מרכז הספרייט כמקור.

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

סיכום מדגם זה

הפעם, הסברנו את התהליך המוקדש למחוות. במדגם, אנו יוצרים רק תהליך צביטה, אבל יש גם "תנועות" ו "מחזיק". כדי לגלות אילו מחוות זמינות, עיין בעזרה של XNA Game Studio 4.0 עבור הפעלות GestureType.

אתה יכול ליישם את אותו הדבר ממידע המגע המתקבל מהשיטה TouchPanel.GetState מבלי להשתמש בשיטות או מבנים ספציפיים למחווה, אך במקרה זה, יהיה עליך לחשב את המהירות של ניהול מזהה רב-מגע, זמן מגע, תנועות וכו 'בעצמך. על ידי שימוש בשיטות ספציפיות למחוות, ניתן לפשט יישומים אלה, ויש גם את היתרון שניתן להפעיל את כל המשחקים והיישומים באותו אופן.

בעת יצירת תהליך בלוח מגע בעצמך, אם באפשרותך להחליף תהליך דומה כמחווה, מומלץ להשתמש בו.

תכנות! - 5.צביטה לסיבוב שדונים

אודות מדגם זה

צביטה מתייחסת בדרך כלל ל"צביטה" ו"מתיחה", אך תהליך הצביטה של XNA Game Studio 4.0 אינו מגביל באופן ספציפי את התהליך לשני אלה, כך שתוכל גם לבצע פעולות המעגלות נקודת מגע אחת סביב נקודת מגע אחרת.

כאן, אני רוצה לסובב את הספרייט בשיטת הפעולה הזו. אגב, לא הופיעו הפעם שיטות או שיעורים חדשים, והיא מבוססת על קנה המידה הקודם.

בתיאור הקוד לדוגמה במאמר זה, אותם חלקים כמו דוגמת שינוי קנה המידה הקודמת מושמטים.

מטרות התוכנית לדוגמה

על ידי סיבוב שתי נקודות המגע, הספרייט מסתובב. פעולת קנה המידה הקודמת פועלת גם היא.

図 2 :タッチポイントを回してスプライトを回転させています
איור 2: סיבוב הספרייט על-ידי סיבוב נקודת המגע

תכנית - הכרזה על שדות

"כמות סיבוב ספרייט" ו"זווית סיבוב אחרונה " מתווספים לתוכנית קנה המידה הקודמת. כל הזוויות מחושבות ברדיאנים.

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

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

תכנית - תהליך הרוטציה

תהליך הסיבוב מתבצע במהלך מחוות צביטה באותו אופן כמו בעת שינוי קנה מידה.

אני לא אכנס ליותר מדי פרטים על חישוב הסיבוב כי זה סיפור מתמטי, אבל אתה יכול לקבל את רדיאן הזווית עם השיטה "Math.Atan2" על ידי מציאת וקטור ההפרש מנקודת מגע 1 לנקודת מגע 2. מצא את ההבדל בין הזווית המתקבלת לבין הזווית שנרכשה בעבר והוסף אותה לזווית הסיבוב של הספרייט.

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

תוכנית - ציור שדונים

אין שינויים משמעותיים בציור שדונים. הארגומנט החמישי של פעולת השירות SpriteBacth.Draw מוגדר לזווית הסיבוב המחושבת.

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

סיכום מדגם זה

הפעם, ניסיתי לסובב את הספרייט על ידי פעולת צביטה. אנחנו לא משתמשים בכיתות חדשות במיוחד, אבל אני מקווה שאתה מבין שאנחנו יכולים לממש עיבוד יישומי המבוסס על הפונקציות שסופקו.

סוף סוף

עברנו על דוגמאות והדגמנו את היישום של אינטראקציות מגע באמצעות Windows Phone 7 ו- XNA Game Studio 4.0. התוכן כלל רכישה ומניפולציה של מגע יחיד ומולטי-טאץ' של מידע מגע, ועיבוד על ידי מניפולציה של מחוות מגע בשיטות ספציפיות למחוות.

הפעם, התמקדתי בלוח המגע, אבל עדיין יש כמה פונקציות שעדיין לא הצגתי. Windows Phone 7 כולל גם תכונות קלט חדשות ב- XNA Game Studio 4.0, כגון קלט מד תאוצה וקלט קולי. יש כמה תכונות מעניינות שלא הצלחתי להציג הפעם, אז בבקשה תהנה לחקור את הפונקציות שאתה רוצה להשתמש בהן.