รองรับอุปกรณ์ควบคุมเกมหลายตัว

แม้ว่าเกมส่วนใหญ่ออกแบบมาเพื่อรองรับผู้ใช้ 1 คนต่ออุปกรณ์ Android 1 เครื่อง คุณยังสามารถรองรับผู้ใช้หลายคนด้วยตัวควบคุมเกมที่ ที่เชื่อมต่อพร้อมกันได้ในอุปกรณ์ Android เครื่องเดียวกัน

บทเรียนนี้ครอบคลุมเทคนิคพื้นฐานบางประการสำหรับการจัดการการป้อนข้อมูลในซิงเกิลของคุณ เกมที่มีอุปกรณ์แบบผู้เล่นหลายคนจากตัวควบคุมหลายรายการที่เชื่อมต่ออยู่ ซึ่งรวมถึง การดูแลรักษาการแมประหว่างรูปโปรไฟล์ผู้เล่นและอุปกรณ์ควบคุมแต่ละเครื่อง และ ประมวลผลเหตุการณ์อินพุตตัวควบคุมอย่างเหมาะสม

แมปผู้เล่นกับรหัสอุปกรณ์ตัวควบคุม

เมื่อเกมคอนโทรลเลอร์เชื่อมต่อกับอุปกรณ์ Android ระบบจะ กำหนดรหัสอุปกรณ์เป็นจำนวนเต็ม คุณสามารถรับรหัสอุปกรณ์สำหรับการเชื่อมต่อ ตัวควบคุมเกมโดยโทรหา InputDevice.getDeviceIds() ดังที่แสดงในยืนยันว่าตัวควบคุมเกมเชื่อมต่อแล้ว จากนั้น คุณสามารถเชื่อมโยง รหัสอุปกรณ์ที่มีผู้เล่นอยู่ในเกม และประมวลผลการดำเนินการในเกมสำหรับผู้เล่นแต่ละคนแยกกัน

หมายเหตุ: ในอุปกรณ์ที่ใช้ Android 4.1 (API ระดับ 16) ขึ้นไป คุณสามารถดูตัวบอกลักษณะของอุปกรณ์อินพุตได้โดยใช้ getDescriptor() ซึ่งแสดงผลค่าที่ไม่ซ้ำกัน ค่าสตริงถาวรสำหรับอุปกรณ์อินพุต ตัวบ่งชี้ต่างจากรหัสอุปกรณ์ จะไม่เปลี่ยนแปลงแม้ว่าอุปกรณ์อินพุตจะไม่ได้เชื่อมต่อ เชื่อมต่อใหม่ หรือ กำหนดค่าใหม่หรือไม่

ข้อมูลโค้ดด้านล่างแสดงวิธีใช้ SparseArray เพื่อเชื่อมโยงอวาตาร์ของผู้เล่นกับตัวควบคุมที่เจาะจง ในตัวอย่างนี้ ตัวแปร mShips จัดเก็บคอลเล็กชันของออบเจ็กต์ Ship รายการ ใหม่ ระบบจะสร้างรูปโปรไฟล์ของผู้เล่นในเกมเมื่อผู้ใช้แนบตัวควบคุมใหม่ และนำออกเมื่อมีการนำตัวควบคุมที่เกี่ยวข้องออก

การติดต่อกลับของ onInputDeviceAdded() และ onInputDeviceRemoved() เป็นส่วนหนึ่งของชั้นแอบสแตรกต์ที่แนะนำใน การรองรับตัวควบคุมใน Android เวอร์ชันต่างๆ โดยการใช้สิ่งเหล่านี้ Listener Callback เกมของคุณสามารถระบุรหัสอุปกรณ์ของตัวควบคุมเกมเมื่อ มีการเพิ่มหรือนำตัวควบคุมออก การตรวจหานี้เข้ากันได้กับ Android 2.3 (API ระดับ 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); } 

หมายเหตุ: ตามแนวทางปฏิบัติที่ดีที่สุด เมื่อผู้ใช้ เกมคอนโทรลเลอร์ยกเลิกการเชื่อมต่อ คุณควรหยุดเกมชั่วคราวแล้วถามผู้ใช้ ต้องการเชื่อมต่อใหม่