विंडोज फोन 7 भाग 4 चुटकी के लिए खेल के विकास में टच इंटरैक्शन

पेज अद्यतन :
पेज निर्माण की तारीख :

प्रोग्रामिंग! - 4. चुटकी, स्प्राइट्स स्केल करने के लिए खिंचाव

इस नमूने के बारे में

आधुनिक स्मार्टफ़ोन, जैसे कि छवि दर्शक, आपको अपनी उंगलियों के बीच की दूरी को बढ़ाने या कम करने के लिए दो उंगलियों का उपयोग करके एक छवि को बड़ा और सिकोड़ने की अनुमति देते हैं। आप विंडोज फोन 7 पर इंटरनेट एक्सप्लोरर के साथ भी ऐसा कर सकते हैं। इस क्रिया को विंडोज फोन 7 में "चुटकी, खिंचाव" कहा जाता है।

पिंचिंग और स्ट्रेचिंग के अलावा, आप स्क्रीन पर एक बिंदु को संक्षेप में स्पर्श (टैप) करने के लिए "टैप" और स्क्रीन को जल्दी से ट्रेस करने के लिए "फ्लिक" जैसी क्रियाओं का भी उपयोग कर सकते हैं। इन क्रियाओं को सामूहिक रूप से इशारों के रूप में जाना जाता है।

इस कार्यक्रम में, मैं इस चुटकी और खिंचाव ऑपरेशन द्वारा स्क्रीन पर प्रदर्शित स्प्राइट को बड़ा और कम करना चाहता हूं। इसके अलावा, पिछली बार तक, मैंने सीधे टच पैनल की जानकारी प्राप्त की और इसे संसाधित किया, लेकिन इस बार मैं इशारों के लिए समर्पित विधियों का उपयोग करके स्पर्श संचालन को संभालना चाहता हूं।

इस नमूना कार्यक्रम के लक्ष्य

स्प्राइट को बड़ा करने और सिकोड़ने के लिए चुटकी और खिंचाव संचालन।

図 1 :ストレッチでスプライトを拡大
चित्र 1: स्प्राइट को बड़ा करने के लिए खिंचाव

कार्यक्रम - फ़ील्ड घोषित करना

फ़ील्ड घोषणा में कोई नया वर्ग नहीं है, लेकिन इसमें "बनावट का केंद्र समन्वय", "स्प्राइट का आवर्धन", और "चुटकी लेते समय अंतिम दो स्पर्श पदों के बीच की दूरी" है।

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

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

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

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

कार्यक्रम - इशारों को सक्षम करना

इस बार, हम एक इशारा-केवल प्रक्रिया करेंगे, लेकिन डिफ़ॉल्ट स्थिति में, किसी भी इशारे का उपयोग नहीं किया जा सकता है। प्रत्येक गेस्चर जानकारी पुनर्प्राप्त करने के लिए, आपको टचपैनल.सक्षम जेज्चर गुण के लिए उपयोग किए जाने वाले जेस्चर को सेट करना होगा।

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

सभी इशारों को सक्षम करने से प्रदर्शन प्रभावित होता है, इसलिए सुनिश्चित करें कि आप केवल उन इशारों को सेट करते हैं जिनका आप उपयोग करना चाहते हैं। यहां, "जेस्चरटाइप.पिंच" चुटकी ऑपरेशन जानकारी प्राप्त करने के लिए सेट किया गया है और "जेस्चर टाइप.पिंचकंप्लीट" यह इंगित करने के लिए सेट है कि चुटकी प्रक्रिया पूरी हो गई है। सेटिंग स्थान गेम कन्स्ट्रक्टर में सेट किया गया है।

कार्यक्रम - बनावट लोड हो रहा है

लोडिंग बनावट पहले की तरह ही है, लेकिन इस बार हम "बनावट के केंद्र समन्वय" की गणना कर रहे हैं। ऐसा इसलिए है क्योंकि स्प्राइट को स्केल करते समय, यह मूल के रूप में केंद्र समन्वय के साथ तराजू करता है।

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

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

कार्यक्रम - इशारे की जानकारी प्राप्त करें

हमें गेम.अपडेट विधि में इशारे की जानकारी (यहां चुटकी) मिलती है। जेस्चर प्रोसेसिंग आपके द्वारा सक्षम किए गए कई इशारों को दोहराने के रूप में है। "टचकलेक्शन" संरचना जो पिछली बार तक उपयोग की गई थी, का उपयोग नहीं किया जाता है।

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

इशारे की जानकारी के लिए लूप में टचपैनल.आईएसजीचर उपलब्ध संपत्ति की स्थिति की जांच करें और जांचें कि क्या निम्नलिखित इशारा जानकारी मौजूद है: यदि आपके पास निम्न जेस्चर जानकारी है, तो जेस्चर जानकारी प्राप्त करने के लिए "टचपैनल.रीडगेस्टर" विधि का उपयोग करें।

"जेस्चरसैंपल.जेस्चर टाइप" जानकारी संग्रहीत करता है कि कौन सा इशारा प्रकार शामिल है, इसलिए इसके आधार पर स्विच स्टेटमेंट के साथ प्रक्रिया को शाखा दें। इस नमूने में, कन्स्ट्रक्टर "गेस्चर टाइप.पिंच" और "गेस्चर टाइप.पिंचकंप्लीट" एनम्स को "टचपैनल.सक्षम गेस्चर्स" संपत्ति पर सेट करता है, इसलिए वे क्रमशः शाखित होते हैं।

कार्यक्रम - चुटकी इशारा हैंडलिंग

हम जो कर रहे हैं उसके लिए कोड में टिप्पणियों को देखना तेज़ है, लेकिन संक्षेप में हम क्या कर रहे हैं, हम पिछले दो टचपॉइंट्स के बीच की दूरी और इस बार दो बिंदुओं के बीच टचपॉइंट दूरी के बीच का अंतर पाते हैं, और स्केल वैल्यू को बढ़ाने या घटाने के लिए उस अंतर का उपयोग करते हैं।

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;

दो स्पर्श पदों को क्रमशः "जेस्चरसैंपल.पोजिशन" और "जेस्चरसैंपल.पोजिशन 2" के साथ प्राप्त किया जा सकता है। आप दो प्राप्त वैक्टरों के बीच अंतर को घटा सकते हैं और "वेक्टर 2.लंबाई" विधि को कॉल करके दो बिंदुओं के बीच की दूरी ज्ञात कर सकते हैं।

वैसे, यहां हम पिछली दूरी को 0 के रूप में परिभाषित करते हैं जब पिंचिंग नहीं की जाती है, इसलिए पिंचिंग शुरू होने पर और दूसरे और बाद के छोरों में प्रक्रिया को ब्रांच किया जाता है। ऐसा इसलिए है क्योंकि पिंचिंग की पहली बार, कोई पिछली दूरी नहीं है, इसलिए स्केल करने की कोई आवश्यकता नहीं है।

इसके अलावा, इस बार हम केवल दो गुणों का उपयोग करते हैं, "जेस्चरसैंपल.पोजिशन" और "जेस्चरसैंपल.पोजिशन 2", लेकिन "जेस्चरसैंपल.डेल्टा" और "जेस्चरसैंपल.डेल्टा 2" गुण भी हैं, जो पिछले स्पर्श स्थिति से अंतर की जानकारी प्राप्त कर सकते हैं। प्रत्येक में दो गुण हैं, लेकिन यह बहु-स्पर्श के लिए है, और इशारों के लिए जो केवल एकल स्पर्श का उपयोग करते हैं, आप "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();

इस नमूने का सारांश

इस बार, हमने इशारों को समर्पित प्रक्रिया को समझाया। नमूने में, हम केवल एक चुटकी प्रक्रिया बनाते हैं, लेकिन "फ़्लिक्स" और "होल्ड" भी होते हैं। यह जानने के लिए कि कौन से इशारे उपलब्ध हैं, जेस्चर टाइप एनम्स के लिए एक्सएनए गेम स्टूडियो 4.0 सहायता देखें।

आप जेस्चर-विशिष्ट विधियों या संरचनाओं का उपयोग किए बिना टचपैनल.गेटस्टेट विधि से प्राप्त स्पर्श जानकारी से एक ही चीज़ को लागू कर सकते हैं, लेकिन उस स्थिति में, आपको मल्टी-टच आईडी प्रबंधन, स्पर्श समय, फ़्लिक्स आदि की गति की गणना करने की आवश्यकता होगी। इशारा-विशिष्ट विधियों का उपयोग करके, इन कार्यान्वयन को सरल बनाया जा सकता है, और यह भी लाभ है कि सभी गेम और एप्लिकेशन को उसी तरह से संचालित किया जा सकता है।

जब आप स्वयं एक स्पर्श पैनल प्रक्रिया बनाते हैं, यदि आप इशारे के समान प्रक्रिया को प्रतिस्थापित कर सकते हैं, तो हम अनुशंसा करते हैं कि आप इसका उपयोग करें।

प्रोग्रामिंग! - 5. चुटकी स्प्राइट्स बारी बारी से करने के लिए

इस नमूने के बारे में

पिंचिंग आमतौर पर "पिंचिंग" और "स्ट्रेचिंग" को संदर्भित करता है, लेकिन एक्सएनए गेम स्टूडियो 4.0 की चुटकी प्रक्रिया विशेष रूप से प्रक्रिया को उन दो तक सीमित नहीं करती है, इसलिए आप उन ऑपरेशनों को भी कर सकते हैं जो एक टचपॉइंट को दूसरे टचपॉइंट के चारों ओर सर्कल करते हैं।

यहां, मैं उस ऑपरेशन विधि के साथ स्प्राइट को घुमाना चाहता हूं। वैसे, इस बार कोई नई विधियां या कक्षाएं दिखाई नहीं दीं, और यह पिछले स्केलिंग पर आधारित है।

इस आलेख में नमूना कोड के वर्णन में, पिछले स्केलिंग नमूने के समान भागों को छोड़ दिया जाता है।

इस नमूना कार्यक्रम के लक्ष्य

दो टचपॉइंट्स को घुमाकर, स्प्राइट घूमता है। पिछला स्केलिंग ऑपरेशन भी काम करता है।

図 2 :タッチポイントを回してスプライトを回転させています
चित्रा 2: टचपॉइंट को मोड़कर स्प्राइट को घुमाना

कार्यक्रम - फ़ील्ड घोषित करना

"स्प्राइट रोटेशन राशि" और "अंतिम रोटेशन कोण" पिछले स्केलिंग प्रोग्राम में जोड़े जाते हैं। सभी कोणों की गणना रेडियन में की जाती है।

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

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

कार्यक्रम - रोटेशन प्रक्रिया

रोटेशन प्रक्रिया चुटकी इशारों के दौरान उसी तरह से की जाती है जैसे स्केलिंग करते समय।

मैं रोटेशन की गणना करने के बारे में बहुत अधिक विस्तार में नहीं जाऊंगा क्योंकि यह एक गणित की कहानी है, लेकिन आप टचपॉइंट 1 से टचपॉइंट 2 तक अंतर वेक्टर को ढूंढकर "मैथ.अटान 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;
}

कार्यक्रम - ड्राइंग स्प्राइट्स

स्प्राइट्स ड्राइंग में कोई बड़ा बदलाव नहीं है। स्प्राइटबैक्थ.ड्रा विधि का पांचवां तर्क गणना किए गए रोटेशन कोण पर सेट है।

// スプライトの描画準備
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 और एक्सएनए गेम स्टूडियो 4.0 का उपयोग करके स्पर्श इंटरैक्शन के कार्यान्वयन का प्रदर्शन किया। सामग्री में सिंगल-टच और मल्टी-टच टच अधिग्रहण और स्पर्श जानकारी में हेरफेर, और इशारा-विशिष्ट तरीकों का उपयोग करके स्पर्श इशारा हेरफेर द्वारा प्रसंस्करण शामिल था।

इस बार, मैंने टच पैनल पर ध्यान केंद्रित किया है, लेकिन अभी भी कुछ फ़ंक्शन हैं जिन्हें मैंने अभी तक पेश नहीं किया है। विंडोज फोन 7 में एक्सएनए गेम स्टूडियो 4.0 में नई इनपुट सुविधाएँ भी शामिल हैं, जैसे एक्सेलेरोमीटर इनपुट और वॉयस इनपुट। कुछ दिलचस्प विशेषताएं हैं जिन्हें मैं इस बार पेश नहीं कर सका, इसलिए कृपया उन कार्यों की खोज का आनंद लें जिनका आप उपयोग करना चाहते हैं।