माउस इनपुट

इस विषय में बताया गया है कि Google Play Games on PC के लिए, माउस इनपुट को कैसे लागू किया जाए. यह उन गेम के लिए है जिनमें इनपुट ट्रांसलेशन मोड, खिलाड़ियों को बेहतर अनुभव नहीं देता.

पीसी पर गेम खेलने वाले लोगों के पास आम तौर पर, टचस्क्रीन के बजाय कीबोर्ड और माउस होता है. इसलिए, यह देखना ज़रूरी है कि आपके गेम में माउस इनपुट की सुविधा काम करती हो. डिफ़ॉल्ट रूप से, Google Play Games on PC, माउस के किसी भी लेफ्ट-क्लिक इवेंट को एक वर्चुअल टैप इवेंट में बदल देता है. इसे "इनपुट ट्रांसलेशन मोड" कहा जाता है.

इस मोड की मदद से, गेम में कुछ बदलाव करके उसे पीसी पर खेला जा सकता है. हालांकि, इससे पीसी पर गेम खेलने वाले लोगों को नेटिव गेम खेलने जैसा अनुभव नहीं मिलता. इसके लिए, हमारा सुझाव है कि आप ये काम करें:

  • दबाकर रखने के बजाय, कॉन्टेक्स्ट मेन्यू के लिए कर्सर घुमाने की सुविधा
  • देर तक दबाकर रखने या कॉन्टेक्स्ट मेन्यू में दिखने वाली अन्य कार्रवाइयों के लिए, राइट क्लिक करें
  • ऐक्शन गेम में, प्रेस और ड्रैग इवेंट के बजाय फ़र्स्ट या थर्ड पर्सन के लिए माउस लुक

पीसी पर इस्तेमाल होने वाले सामान्य यूज़र इंटरफ़ेस (यूआई) पैटर्न के साथ काम करने के लिए, आपको इनपुट ट्रांसलेशन मोड बंद करना होगा.

Google Play Games on PC में इनपुट हैंडलिंग की सुविधा, ChromeOS में मौजूद सुविधा जैसी ही होती है. पीसी पर गेम खेलने की सुविधा से जुड़े बदलावों से, Android पर गेम खेलने वाले सभी लोगों को भी बेहतर अनुभव मिलता है.

इनपुट के अनुवाद मोड को बंद करना

अपनी AndroidManifest.xml फ़ाइल में, android.hardware.type.pc सुविधा के बारे में एलान करें. इससे पता चलता है कि आपका गेम पीसी के हार्डवेयर का इस्तेमाल करता है और इनपुट ट्रांसलेशन मोड को बंद कर देता है. इसके अलावा, required="false" जोड़ने से यह पक्का करने में मदद मिलती है कि आपका गेम, माउस के बिना फ़ोन और टैबलेट पर इंस्टॉल किया जा सकता है. उदाहरण के लिए:

<manifest ...>
  <uses-feature
      android:name="android.hardware.type.pc"
      android:required="false" />
  ...
</manifest>

गेम लॉन्च होने पर, Google Play Games on PC का प्रोडक्शन वर्शन सही मोड पर स्विच हो जाता है. डेवलपर एम्युलेटर में ऐप्लिकेशन चलाते समय, आपको माउस का इनपुट पाने के लिए, टास्क बार आइकॉन पर राइट क्लिक करना होगा. इसके बाद, डेवलपर के विकल्प और फिर पीसी मोड(KiwiMouse) को चुनें.

संदर्भ मेन्यू में &quot;पीसी मोड(KiwiMouse)&quot; को चुने जाने का स्क्रीनशॉट

ऐसा करने के बाद, माउस की गतिविधि की जानकारी View.onGenericMotionEvent से मिलती है. इसमें सोर्स SOURCE_MOUSE होता है, जो यह दिखाता है कि यह माउस इवेंट है.

Kotlin

gameView.setOnGenericMotionListener { _, motionEvent ->
    var handled = false
    if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
        // handle the mouse event here
        handled = true
    }
    handled
}

Java

gameView.setOnGenericMotionListener((view, motionEvent) -> {
    if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
        // handle the mouse event here
        return true;
    }
    return false;
});

माउस के इनपुट को मैनेज करने के बारे में जानकारी पाने के लिए, ChromeOS का दस्तावेज़ देखें.

माउस को घुमाने की सुविधा

माउस के मूवमेंट का पता लगाने के लिए, ACTION_HOVER_ENTER, ACTION_HOVER_EXIT, और ACTION_HOVER_MOVE इवेंट सुनें.

इसका सबसे अच्छा इस्तेमाल, गेम में बटन या ऑब्जेक्ट पर कर्सर घुमाने वाले उपयोगकर्ता का पता लगाने के लिए किया जाता है. इससे आपको हिंट बॉक्स दिखाने या माउसओवर की स्थिति लागू करने का मौका मिलता है, ताकि यह हाइलाइट किया जा सके कि कोई खिलाड़ी क्या चुनने वाला है. उदाहरण के लिए:

Kotlin

gameView.setOnGenericMotionListener { _, motionEvent ->
   var handled = false
   if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
       when(motionEvent.action) {
           MotionEvent.ACTION_HOVER_ENTER -> Log.d("MA", "Mouse entered at ${motionEvent.x}, ${motionEvent.y}")
           MotionEvent.ACTION_HOVER_EXIT -> Log.d("MA", "Mouse exited at ${motionEvent.x}, ${motionEvent.y}")
           MotionEvent.ACTION_HOVER_MOVE -> Log.d("MA", "Mouse hovered at ${motionEvent.x}, ${motionEvent.y}")
       }
       handled = true
   }

   handled
}

Java

gameView.setOnGenericMotionListener((view, motionEvent) -> {
    if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_HOVER_ENTER:
                Log.d("MA", "Mouse entered at " + motionEvent.getX() + ", " + motionEvent.getY());
                break;
            case MotionEvent.ACTION_HOVER_EXIT:
                Log.d("MA", "Mouse exited at " + motionEvent.getX() + ", " + motionEvent.getY());
                break;
            case MotionEvent.ACTION_HOVER_MOVE:
                Log.d("MA", "Mouse hovered at " + motionEvent.getX() + ", " + motionEvent.getY());
                break;
        }
        return true;
    }
    return false;
});

माउस के बटन को हैंडल करना

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

बटन दबाने की कार्रवाइयों को मैनेज करने के लिए, ACTION_DOWN और ACTION_UP का इस्तेमाल करें. इसके बाद, getActionButton का इस्तेमाल करके यह पता लगाएं कि किस बटन ने कार्रवाई ट्रिगर की है या getButtonState का इस्तेमाल करके सभी बटन की स्थिति का पता लगाएं.

इस उदाहरण में, getActionButton का नतीजा दिखाने के लिए, enum का इस्तेमाल किया गया है:

Kotlin

enum class MouseButton {
   LEFT,
   RIGHT,
   UNKNOWN;
   companion object {
       fun fromMotionEvent(motionEvent: MotionEvent): MouseButton {
           return when (motionEvent.actionButton) {
               MotionEvent.BUTTON_PRIMARY -> LEFT
               MotionEvent.BUTTON_SECONDARY -> RIGHT
               else -> UNKNOWN
           }
       }
   }
}

Java

enum MouseButton {
    LEFT,
    RIGHT,
    MIDDLE,
    UNKNOWN;
    static MouseButton fromMotionEvent(MotionEvent motionEvent) {
        switch (motionEvent.getActionButton()) {
            case MotionEvent.BUTTON_PRIMARY:
                return MouseButton.LEFT;
            case MotionEvent.BUTTON_SECONDARY:
                return MouseButton.RIGHT;
            default:
                return MouseButton.UNKNOWN;
        }
    }
}

इस उदाहरण में, कार्रवाई को कर्सर घुमाने वाले इवेंट की तरह ही हैंडल किया जाता है:

Kotlin

// Handle the generic motion event
gameView.setOnGenericMotionListener { _, motionEvent ->
   var handled = false
   if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
       when (motionEvent.action) {
           MotionEvent.ACTION_BUTTON_PRESS -> Log.d(
               "MA",
               "${MouseButton.fromMotionEvent(motionEvent)} pressed at ${motionEvent.x}, ${motionEvent.y}"
           )
           MotionEvent.ACTION_BUTTON_RELEASE -> Log.d(
               "MA",
               "${MouseButton.fromMotionEvent(motionEvent)} released at ${motionEvent.x}, ${motionEvent.y}"
           )
       }
       handled = true
   }

   handled
}

Java

gameView.setOnGenericMotionListener((view, motionEvent) -> {
    if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_BUTTON_PRESS:
                Log.d("MA", MouseButton.fromMotionEvent(motionEvent) + " pressed at " + motionEvent.getX() + ", " + motionEvent.getY());
                break;
            case MotionEvent.ACTION_BUTTON_RELEASE:
                Log.d("MA", MouseButton.fromMotionEvent(motionEvent) + " released at " + motionEvent.getX() + ", " + motionEvent.getY());
                break;
        }
        return true;
    }
    return false;
});

माउस व्हील से स्क्रोल करने की सुविधा को मैनेज करना

हमारा सुझाव है कि आप अपने गेम में, पिंच करके ज़ूम करने के जेस्चर या टच करके खींचने वाली स्क्रोल सुविधाओं के बजाय, माउस के स्क्रोल व्हील का इस्तेमाल करें.

स्क्रोल व्हील की वैल्यू पढ़ने के लिए, ACTION_SCROLL इवेंट को सुनें. पिछले फ़्रेम के बाद से डेल्टा को getAxisValue का इस्तेमाल करके वापस पाया जा सकता है. इसके लिए, वर्टिकल ऑफ़सेट के लिए AXIS_VSCROLL और हॉरिज़ॉन्टल ऑफ़सेट के लिए AXIS_HSCROLL का इस्तेमाल करें. उदाहरण के लिए:

Kotlin

gameView.setOnGenericMotionListener { _, motionEvent ->
   var handled = false
   if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
       when (motionEvent.action) {
           MotionEvent.ACTION_SCROLL -> {
               val scrollX = motionEvent.getAxisValue(MotionEvent.AXIS_HSCROLL)
               val scrollY = motionEvent.getAxisValue(MotionEvent.AXIS_VSCROLL)
               Log.d("MA", "Mouse scrolled $scrollX, $scrollY")
           }
       }
       handled = true
   }
   handled
}

Java

gameView.setOnGenericMotionListener((view, motionEvent) -> {
    if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_SCROLL:
                float scrollX = motionEvent.getAxisValue(MotionEvent.AXIS_HSCROLL);
                float scrollY = motionEvent.getAxisValue(MotionEvent.AXIS_VSCROLL);
                Log.d("MA", "Mouse scrolled " + scrollX + ", " + scrollY);
                break;
        }
        return true;
    }
    return false;
});

माउस इनपुट कैप्चर करना

कुछ गेम में, माउस कर्सर को पूरी तरह से कंट्रोल करने की ज़रूरत होती है. जैसे, पहले या तीसरे व्यक्ति के ऐक्शन गेम, जिनमें माउस के मूवमेंट को कैमरे के मूवमेंट पर मैप किया जाता है. माउस का पूरा कंट्रोल पाने के लिए, View.requestPointerCapture() को चालू करें.

requestPointerCapture() का इस्तेमाल सिर्फ़ तब किया जा सकता है, जब आपके व्यू वाली व्यू हैरारकी पर फ़ोकस किया गया हो. इस वजह से, onCreate कॉलबैक में पॉइंटर कैप्चर नहीं किया जा सकता. आपको माउस पॉइंटर को कैप्चर करने के लिए, प्लेयर के साथ इंटरैक्शन होने का इंतज़ार करना चाहिए. जैसे, मुख्य मेन्यू के साथ इंटरैक्ट करते समय. इसके अलावा, onWindowFocusChanged कॉलबैक का इस्तेमाल किया जा सकता है. उदाहरण के लिए:

Kotlin

override fun onWindowFocusChanged(hasFocus: Boolean) {
   super.onWindowFocusChanged(hasFocus)

   if (hasFocus) {
       gameView.requestPointerCapture()
   }
}

Java

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    if (hasFocus) {
        View gameView = findViewById(R.id.game_view);
        gameView.requestPointerCapture();
    }
}

requestPointerCapture() से कैप्चर किए गए इवेंट, उस फ़ोकस किए जा सकने वाले व्यू को भेजे जाते हैं जिसने OnCapturedPointerListener रजिस्टर किया है. उदाहरण के लिए:

Kotlin

gameView.focusable = View.FOCUSABLE
gameView.setOnCapturedPointerListener { _, motionEvent ->
    Log.d("MA", "${motionEvent.x}, ${motionEvent.y}, ${motionEvent.actionButton}")
    true
}

Java

gameView.setFocusable(true);
gameView.setOnCapturedPointerListener((view, motionEvent) -> {
    Log.d("MA", motionEvent.getX() + ", " + motionEvent.getY() + ", " + motionEvent.getActionButton());
    return true;
});

माउस कैप्चर करने की सुविधा को रिलीज़ करने के लिए, View.releasePointerCapture() को लागू करें. जैसे, खिलाड़ियों को पॉज़ मेन्यू के साथ इंटरैक्ट करने की अनुमति देने के लिए.