تعاملات لمسی در توسعه بازی برای ویندوز فون 7 قسمت 4 پینچ

صفحه به روز شده :
تاریخ ایجاد صفحه :

برنامه نویسی! - 4.Pinch, کشش به sprites مقیاس

درباره این نمونه

گوشی های هوشمند مدرن مانند بینندگان تصویر به شما این امکان را می دهند که با استفاده از دو انگشت برای افزایش یا کوچک کردن فاصله بین انگشتان تان، یک تصویر را بزرگ و کوچک کنید. شما می توانید همین کار را با اینترنت اکسپلورر در ویندوز فون 7 انجام دهید. این عمل در ویندوز فون ۷ «پینچ، کشش» نامیده می شود.

علاوه بر pinching و کشش، شما همچنین می توانید اقداماتی مانند "شیر" به طور خلاصه لمس (شیر) یک نقطه بر روی صفحه نمایش و "تلنگر" به سرعت ردیابی صفحه نمایش استفاده کنید. به این اعمال به طور دسته جمعی ژست گفته می شود.

در این برنامه می خواهم اسپریت نمایش داده شده روی صفحه توسط این عمل پینچ و کشش را بزرگ و کاهش بدهم. همچنین تا آخرین بار به طور مستقیم اطلاعات پنل لمسی را به دست آوردم و پردازش کردم، اما این بار می خواهم با استفاده از روش های اختصاص داده شده به ژست ها، عملیات لمسی را اداره کنم.

اهداف این برنامه نمونه

پینچ و عملیات کشش برای بزرگ شدن و کوچک کردن جوانه.

図 1 :ストレッチでスプライトを拡大
شکل 1 : کشش برای بزرگ کردن sprite

برنامه - اعلام زمینه ها

هیچ کلاس جدیدی در اعلامیه میدان وجود ندارد، اما دارای "مختصات مرکز بافت"، "بزرگنمایی اسپریت"، و "فاصله بین دو موقعیت لمسی آخر در هنگام پینچینگ" است.

/// <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" قرار است برای به دست آوردن اطلاعات عملیات pinch و "GestureType.PinchComplete" قرار است نشان می دهد که فرایند پینچ کامل است. محل تنظیم در سازنده بازی تنظیم شده است.

برنامه - بارگذاری بافت

بارگذاری بافت ها مانند قبل است، اما این بار در حال محاسبه «مختصات مرکز بافت» هستیم. این به این دلیل است که هنگام پوسته پوسته شدن یک اسپریت، با هماهنگی مرکز به عنوان مبدا مقیاس می شود.

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

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

برنامه -- دریافت اطلاعات ژست

ما اطلاعات ژست (pinch در اینجا) در روش 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" enums به اموال "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" پیدا کنید.

به هر حال، در اینجا فاصله قبلی را به صورت ۰ تعریف می کنیم که پینچینگ انجام نمی شود، بنابراین فرایند در هنگام شروع پینچینگ و در حلقه های دوم و بعدی شاخه می شود. این به این دلیل است که اولین بار پینچینگ، فاصله قبلی وجود ندارد، بنابراین نیازی به مقیاس نیست.

همچنین این بار تنها از دو خواص "GestureSample.Position" و "GestureSample.Position2" استفاده می کنیم، اما خواص "GestureSample.Delta" و "GestureSample.Delta2" نیز وجود دارد که می تواند اطلاعات تفاوت را از موقعیت لمسی قبلی دریافت کند. هر کدام دو خواص وجود دارد، اما این برای چند لمسی است، و برای ژست هایی که تنها از تک لمسی استفاده می کنند، از خواص بدون "۲" استفاده خواهید کرد.

برنامه - دست زدن به زمانی که ژست پینچ کامل می شود

هنگامی که ژست پینچ کامل است (آزاد کردن هر دو انگشت از پانل لمسی)، فاصله بین دو نقطه قبلی به ۰ برمی گردد. در اصل، ممکن است بهتر باشد از یک پرچم جداگانه استفاده شود، اما از آنجا که لمس همان موقعیت با دو انگشت از نظر فیزیکی غیرممکن است، فاصله ۰ به عنوان پینچینگ تعریف نمی شود. (اگر وضوح پایین باشد، ممکن است می توان همان موقعیت را لمس کرد ...)

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

برنامه -- نقاشی Sprites

من نمی خواهم به جزئیات بیش از حد در اینجا به دلیل آن را فقط در مورد کشیدن sprite است، اما من sprite در مرکز صفحه نمایش قرار داده و ارزش مقیاس محاسبه شده با بزرگ کردن و کوچک کردن آن را با مرکز sprite به عنوان مبدا کشیده است.

// スプライトの描画準備
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 بازی استودیو 4.0 کمک برای Enums GestureType.

شما می توانید همان چیزی را از اطلاعات لمسی به دست آمده از روش TouchPanel.GetState بدون استفاده از روش ها یا ساختارهای خاص ژست پیاده سازی کنید، اما در آن صورت، شما نیاز به محاسبه سرعت مدیریت شناسه چند لمسی، زمان لمسی، تلنگر و غیره خودتان خواهید داشت. با استفاده از روش های خاص ژست، می توان این پیاده سازی ها را ساده کرد، و همچنین این مزیت وجود دارد که تمام بازی ها و برنامه های کاربردی را می توان به همان شیوه عمل کرد.

هنگامی که شما ایجاد یک فرایند پانل لمسی خودتان, اگر شما می توانید یک فرایند مشابه به عنوان یک ژست جایگزین, ما توصیه می کنیم که شما استفاده از این.

برنامه نویسی! - 5.Pinch به چرخش sprites

درباره این نمونه

پینچینگ معمولاً به «پینچینگ» و «کشش» اشاره دارد، اما فرایند پینچ XNA Game Studio ۴٫۰ به طور خاص فرایند را به آن دو محدود نمی کند، بنابراین شما همچنین می توانید عملیات هایی را انجام کنید که یک نقطه لمسی را در اطراف نقطه لمسی دیگری دایره می کنند.

در اینجا می خواهم اسپریت را با آن روش عمل بچرخانم. به هر حال این بار هیچ روش یا کلاس جدیدی ظاهر نمی شد و بر اساس پوسته پوسته شدن قبلی است.

در شرح کد نمونه در این مقاله، همان قسمت های نمونه پوسته پوسته شدن قبلی حذف می شود.

اهداف این برنامه نمونه

با چرخاندن دو نقطه لمسی، اسپریت می چرخد. عملیات پوسته پوسته شدن قبلی نیز کار می کند.

図 2 :タッチポイントを回してスプライトを回転させています
شکل 2 : چرخش sprite با تبدیل نقطه لمسی

برنامه - اعلام زمینه ها

"مقدار چرخش اسپریت" و "آخرین زاویه چرخش" به برنامه پوسته پوسته شدن قبلی اضافه می شوند. همه زاویه ها در رادیان محاسبه می شوند.

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

برنامه -- نقاشی Sprites

هیچ تغییر عمده ای در ترسیم اسپریت ها وجود ندارد. آر استدلال پنجم روش 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();

خلاصه این نمونه

این بار سعی کردم با عمل پینچ اسپریت را بچرخانم. ما از هیچ کلاس جدیدی به طور خاص استفاده نمی کنیم، اما امیدوارم بفهمید که ما می توانیم پردازش کاربردی را بر اساس توابع ارائه شده تحقق بفهمیم.

در آخر

ما از طریق نمونه راه می رفت و نشان داد پیاده سازی تعاملات لمسی با استفاده از ویندوز فون 7 و XNA بازی استودیو 4.0. محتوا شامل اکتساب لمسی تک لمسی و چند لمسی و دستکاری اطلاعات لمسی، و پردازش با دستکاری ژست لمسی با استفاده از روش های خاص ژست بود.

این بار روی پنل لمسی تمرکز کرده ام اما هنوز برخی توابع وجود دارند که هنوز معرفی نکرده ام. ویندوز فون ۷ همچنین شامل ویژگی های ورودی جدید در XNA Game Studio 4.0 مانند ورودی شتاب سنج و ورودی صوتی است. برخی از ویژگی های جالب است که من نمی تواند این بار معرفی وجود دارد, بنابراین لطفا لذت بردن از کاوش توابع شما می خواهید برای استفاده.