एक से ज़्यादा गेम कंट्रोलर के साथ काम करें

ज़्यादातर गेम इस तरह से डिज़ाइन किए जाते हैं कि वे हर Android डिवाइस पर एक ही उपयोगकर्ता को इस्तेमाल कर सकें. हालांकि, साथ ही, ऐसे कई लोगों के लिए गेम कंट्रोलर का इस्तेमाल किया जा सकता है जिन्हें एक ही समय पर, एक ही Android डिवाइस से कनेक्ट हो जाते हैं.

इस लेसन में, आपके सिंगल मॉडल में इनपुट को मैनेज करने के लिए कुछ बुनियादी तकनीकों के बारे में बताया गया है कनेक्ट किए गए कई कंट्रोलर की मदद से, एक से ज़्यादा खिलाड़ी वाले डिवाइस पर गेम. इसमें ये शामिल हैं खिलाड़ी के अवतारों और हर कंट्रोलर डिवाइस के बीच मैपिंग बनाए रखना और कंट्रोलर के इनपुट इवेंट को सही तरीके से प्रोसेस करना.

खिलाड़ियों को कंट्रोलर डिवाइस आईडी से मैप करें

जब गेम कंट्रोलर को किसी Android डिवाइस से कनेक्ट किया जाता है, तो सिस्टम उसे एक पूर्णांक डिवाइस आईडी असाइन करता है. 'कनेक्ट किए गए' खाते के लिए, डिवाइस आईडी पाए जा सकते हैं InputDevice.getDeviceIds() को कॉल करके गेम नियंत्रकों को जोड़ना, जैसा कि पुष्टि करें कि 'गेम कंट्रोलर कनेक्ट हुआ है' सेक्शन में दिखाया गया है. इसके बाद, आपके पास हर साथ ही, हर खिलाड़ी के लिए गेम से जुड़ी कार्रवाइयों को अलग-अलग प्रोसेस करता है.

ध्यान दें: Android 4.1 (एपीआई) वर्शन वाले डिवाइसों पर लेवल 16) और उससे ऊपर के लेवल के लिए, इनपुट डिवाइस का डिस्क्रिप्टर लिया जा सकता है. getDescriptor(), जो यूनीक वैल्यू दिखाता है इनपुट डिवाइस के लिए स्ट्रिंग का स्थायी मान. डिवाइस आईडी से अलग, डिस्क्रिप्टर इनपुट डिवाइस के डिसकनेक्ट होने, फिर से कनेक्ट होने, या फिर से कॉन्फ़िगर किया गया.

नीचे दिया गया कोड स्निपेट, 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);
}

एक से ज़्यादा कंट्रोलर इनपुट प्रोसेस करें

प्रोसेस करने के लिए, आपके गेम को यह लूप एक्ज़ीक्यूट करना चाहिए एक से ज़्यादा नियंत्रकों से इनपुट दें:

  1. पता करें कि कोई इनपुट इवेंट हुआ है या नहीं.
  2. इनपुट सोर्स और उसके डिवाइस आईडी की पहचान करें.
  3. इनपुट इवेंट के कुंजी कोड या ऐक्सिस की वैल्यू से दिखाई गई कार्रवाई के आधार पर, उस डिवाइस आईडी से जुड़े प्लेयर का अवतार अपडेट करना होगा.
  4. यूज़र इंटरफ़ेस को रेंडर और अपडेट करना.

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

ध्यान दें: सबसे सही तरीका यह है कि जब कोई उपयोगकर्ता गेम कंट्रोलर डिसकनेक्ट होने के बाद, आपको गेम को रोकना चाहिए और पूछना चाहिए कि क्या उपयोगकर्ता फिर से कनेक्ट करना चाहता है.