इस विषय में बताया गया है कि 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) को चुनना होगा.
ऐसा करने के बाद, माउस की गतिविधि की जानकारी 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() को लागू करें. इससे खिलाड़ियों को पॉज़ मेन्यू के साथ इंटरैक्ट करने की अनुमति मिलती है.