ज़्यादातर गेम, Android डिवाइस पर एक ही उपयोगकर्ता के साथ काम करने के लिए डिज़ाइन किए जाते हैं. हालांकि, एक ही Android डिवाइस पर एक साथ कनेक्ट किए गए गेम कंट्रोलर की मदद से, एक से ज़्यादा उपयोगकर्ताओं के साथ भी गेम खेला जा सकता है.
इस लेसन में, एक ही डिवाइस पर खेले जाने वाले मल्टीप्लेयर गेम में, कनेक्ट किए गए कई कंट्रोलर से इनपुट मैनेज करने की कुछ बुनियादी तकनीकों के बारे में बताया गया है. इसमें, प्लेयर अवतार और हर कंट्रोलर डिवाइस के बीच मैपिंग बनाए रखना और कंट्रोलर के इनपुट इवेंट को सही तरीके से प्रोसेस करना शामिल है.
प्लेयर को कंट्रोलर डिवाइस आईडी से मैप करना
जब किसी गेम कंट्रोलर को Android डिवाइस से कनेक्ट किया जाता है, तो सिस्टम उसे एक पूर्णांक डिवाइस आईडी असाइन करता है. कनेक्ट किए गए गेम कंट्रोलर के डिवाइस आईडी पाने के लिए, InputDevice.getDeviceIds() को कॉल करें. इसके बारे में पुष्टि करना कि गेम कंट्रोलर कनेक्ट है में बताया गया है. इसके बाद, हर डिवाइस आईडी को अपने गेम में किसी खिलाड़ी से जोड़ा जा सकता है. साथ ही, हर खिलाड़ी के लिए गेम से जुड़ी कार्रवाइयों को अलग-अलग प्रोसेस किया जा सकता है.
इस कोड स्निपेट में, SparseArray का इस्तेमाल करके, किसी प्लेयर के अवतार को किसी कंट्रोलर से जोड़ने का तरीका दिखाया गया है. इस उदाहरण में, mShips वैरिएबल, Ship ऑब्जेक्ट का कलेक्शन सेव करता है. जब कोई उपयोगकर्ता नया कंट्रोलर अटैच करता है, तो गेम में एक नया प्लेयर अवतार बन जाता है. जब कंट्रोलर को हटा दिया जाता है, तो उससे जुड़ा प्लेयर अवतार भी हट जाता है.
onInputDeviceAdded() और onInputDeviceRemoved() कॉलबैक के तरीके, Android के अलग-अलग वर्शन पर कंट्रोलर इस्तेमाल करने की सुविधा में शामिल ऐब्स्ट्रैक्शन लेयर का हिस्सा हैं.
लिसनर कॉलबैक लागू करके, आपका गेम कंट्रोलर के जोड़े या हटाए जाने पर, गेम कंट्रोलर के डिवाइस आईडी की पहचान कर सकता है. यह सुविधा, Android 2.3 (एपीआई लेवल 9) और इसके बाद के वर्शन वाले डिवाइसों पर काम करती है.
Kotlin
private val ships = SparseArray<Ship>()
override fun onInputDeviceAdded(deviceId: Int) {
getShipForID(deviceId)
}
override fun onInputDeviceRemoved(deviceId: Int) {
removeShipForID(deviceId)
}
private fun getShipForID(shipID: Int): Ship {
return ships.get(shipID) ?: Ship().also {
ships.append(shipID, it)
}
}
private fun removeShipForID(shipID: Int) {
ships.remove(shipID)
}
Java
private final SparseArray<Ship> ships = new SparseArray<Ship>();
@Override
public void onInputDeviceAdded(int deviceId) {
getShipForID(deviceId);
}
@Override
public void onInputDeviceRemoved(int deviceId) {
removeShipForID(deviceId);
}
private Ship getShipForID(int shipID) {
Ship currentShip = ships.get(shipID);
if ( null == currentShip ) {
currentShip = new Ship();
ships.append(shipID, currentShip);
}
return currentShip;
}
private void removeShipForID(int shipID) {
ships.remove(shipID);
}
एक से ज़्यादा कंट्रोलर से मिले इनपुट को प्रोसेस करना
एक से ज़्यादा कंट्रोलर से इनपुट प्रोसेस करने के लिए, आपके गेम को यह लूप चलाना चाहिए:
- यह पता लगाता है कि कोई इनपुट इवेंट हुआ है या नहीं.
- इनपुट सोर्स और उसके डिवाइस आईडी की पहचान करें.
- इनपुट इवेंट के मुख्य कोड या ऐक्सिस वैल्यू से मिली जानकारी के आधार पर, उस डिवाइस आईडी से जुड़े प्लेयर अवतार को अपडेट करें.
- यूज़र इंटरफ़ेस को रेंडर और अपडेट करता है.
KeyEvent और MotionEvent इनपुट इवेंट, डिवाइस आईडी से जुड़े होते हैं. आपका गेम इस सुविधा का इस्तेमाल करके यह पता लगा सकता है कि इनपुट इवेंट किस कंट्रोलर से आया है. साथ ही, उस कंट्रोलर से जुड़े प्लेयर अवतार को अपडेट कर सकता है.
यहां दिए गए कोड स्निपेट में बताया गया है कि गेम कंट्रोलर डिवाइस आईडी के हिसाब से, प्लेयर अवतार का रेफ़रंस कैसे पाया जा सकता है. साथ ही, यह भी बताया गया है कि कंट्रोलर पर उपयोगकर्ता के बटन दबाने के आधार पर, गेम को कैसे अपडेट किया जा सकता है.
Kotlin
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (event.source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD) {
event.deviceId.takeIf { it != -1 }?.also { deviceId ->
val currentShip: Ship = getShipForID(deviceId)
// Based on which key was pressed, update the player avatar
// (e.g. set the ship headings or fire lasers)
return true
}
}
return super.onKeyDown(keyCode, event)
}
Java
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)
== InputDevice.SOURCE_GAMEPAD) {
int deviceId = event.getDeviceId();
if (deviceId != -1) {
Ship currentShip = getShipForId(deviceId);
// Based on which key was pressed, update the player avatar
// (e.g. set the ship headings or fire lasers)
...
return true;
}
}
return super.onKeyDown(keyCode, event);
}