Oyununuzda oyun denetleyicilerini destekliyorsanız oyununuzun, Android'in farklı sürümlerini çalıştıran cihazlarda denetleyicilere tutarlı bir şekilde yanıt verdiğinden emin olmak sizin sorumluluğunuzdadır. Bu sayede oyununuz daha geniş bir kitleye ulaşabilir ve oyuncularınız Android cihazlarını değiştirse veya yükseltse bile kumandalarıyla sorunsuz bir oyun deneyiminin keyfini çıkarabilir.
Bu derste, Android 4.1 ve sonraki sürümlerdeki API'lerin geriye dönük uyumlu olarak nasıl kullanılacağını ve oyununuzun Android 3.1 ve sonraki sürümleri çalıştıran cihazlarda aşağıdaki özellikleri desteklemesini nasıl sağlayacağınızı öğrenebilirsiniz:
- Oyun, yeni bir oyun kumandası eklenip eklenmediğini, değiştirildiğini veya kaldırıldığını algılayabilir.
- Oyun, oyun kumandasının özelliklerini sorgulayabilir.
- Oyun, oyun kumandasından gelen hareket etkinliklerini tanıyabilir.
Bu dersteki örnekler, yukarıdan indirilmeye hazır olan örnek ControllerSample.zip
tarafından sağlanan referans uygulamasına dayanır. Bu örnekte, Android'in farklı sürümlerini desteklemek için InputManagerCompat
arayüzünün nasıl uygulanacağı gösterilmektedir. Örneği derlemek için Android 4.1 (API düzeyi 16) veya sonraki bir sürümü kullanmanız gerekir. Örnek uygulama derlendikten sonra, derleme hedefi olarak Android 3.1 (API düzeyi 12) veya sonraki sürümleri çalıştıran tüm cihazlarda çalışır.
Oyun denetleyicisi desteği için API'leri soyutlamaya hazırlanma
Android 3.1 (API düzeyi 12) çalıştıran cihazlarda oyun kumandasının bağlantı durumunun değişip değişmediğini belirleyebilmek istediğinizi varsayalım. Ancak API'ler yalnızca Android 4.1 (API düzeyi 16) ve sonraki sürümlerde kullanılabildiğinden, Android 4.1 ve sonraki sürümleri destekleyen bir uygulama, Android 3.1'den Android 4.0'a kadar olan sürümleri destekleyen bir yedek mekanizma sağlamanız gerekir.
Hangi özelliklerin eski sürümlerde böyle bir yedek mekanizmasının gerekli olduğunu belirlemenize yardımcı olmak amacıyla, Android 3.1 (API düzeyi 12) ve 4.1 (API düzeyi 16) arasında oyun kumandası desteğinin farklılıkları Tablo 1'de verilmiştir.
Kumanda Bilgileri | Denetleyici API'sı | API düzeyi 12 | API düzeyi 16 |
---|---|---|---|
Cihaz Tanımlama | getInputDeviceIds() |
• | |
getInputDevice() |
• | ||
getVibrator() |
• | ||
SOURCE_JOYSTICK |
• | • | |
SOURCE_GAMEPAD |
• | • | |
Bağlantı Durumu | onInputDeviceAdded() |
• | |
onInputDeviceChanged() |
• | ||
onInputDeviceRemoved() |
• | ||
Giriş Etkinliği Tanımlaması | D-pad basın (
KEYCODE_DPAD_UP ,
KEYCODE_DPAD_DOWN ,
KEYCODE_DPAD_LEFT ,
KEYCODE_DPAD_RIGHT ,
KEYCODE_DPAD_CENTER ) |
• | • |
Oyun kumandası düğmesine basma (
BUTTON_A ,
BUTTON_B ,
BUTTON_THUMBL ,
BUTTON_THUMBR ,
BUTTON_SELECT ,
BUTTON_START ,
BUTTON_R1 ,
BUTTON_L1 ,
BUTTON_R2 ,
BUTTON_L2 ) |
• | • | |
Kontrol çubuğu ve şapka geçişi (
AXIS_X ,
AXIS_Y ,
AXIS_Z ,
AXIS_RZ ,
AXIS_HAT_X ,
AXIS_HAT_Y ) |
• | • | |
Analog tetikleyiciye basma (
AXIS_LTRIGGER ,
AXIS_RTRIGGER ) |
• | • |
Platformlar genelinde çalışan, sürüme duyarlı oyun kumandası desteği oluşturmak için soyutlamadan yararlanabilirsiniz. Bu yaklaşım aşağıdaki adımları içerir:
- Oyununuzun gerektirdiği oyun denetleyicisi özelliklerinin uygulanmasını soyutlayan bir ara Java arayüzü tanımlayın.
- Android 4.1 ve sonraki sürümlerde API'leri kullanan arayüzünüzün bir proxy uygulamasını oluşturun.
- Arayüzünüzün Android 3.1 ile Android 4.0 arasındaki sürümler arasında mevcut API'leri kullanan özel bir uygulamasını oluşturun.
- Çalışma zamanında bu uygulamalar arasında geçiş yapma mantığını oluşturun ve oyununuzda arayüzü kullanmaya başlayın.
Uygulamaların farklı Android sürümlerinde geriye dönük uyumlu şekilde çalışabilmesini sağlamak amacıyla soyutlamanın nasıl kullanılabileceği hakkında genel bir bakış için Geriye Doğru Uyumlu Kullanıcı Arayüzü Oluşturma bölümüne bakın.
Geriye dönük uyumluluk için arayüz ekleme
Geriye dönük uyumluluk sağlamak için özel bir arayüz oluşturup sürüme özgü uygulamalar ekleyebilirsiniz. Bu yaklaşımın avantajlarından biri, oyun kumandalarını destekleyen Android 4.1 (API seviyesi 16) herkese açık arayüzleri yansıtmanıza imkan tanımasıdır.
Kotlin
// The InputManagerCompat interface is a reference example. // The full code is provided in the ControllerSample.zip sample. interface InputManagerCompat { val inputDeviceIds: IntArray fun getInputDevice(id: Int): InputDevice fun registerInputDeviceListener( listener: InputManager.InputDeviceListener, handler: Handler? ) fun unregisterInputDeviceListener(listener:InputManager.InputDeviceListener) fun onGenericMotionEvent(event: MotionEvent) fun onPause() fun onResume() interface InputDeviceListener { fun onInputDeviceAdded(deviceId: Int) fun onInputDeviceChanged(deviceId: Int) fun onInputDeviceRemoved(deviceId: Int) } }
Java
// The InputManagerCompat interface is a reference example. // The full code is provided in the ControllerSample.zip sample. public interface InputManagerCompat { ... public InputDevice getInputDevice(int id); public int[] getInputDeviceIds(); public void registerInputDeviceListener( InputManagerCompat.InputDeviceListener listener, Handler handler); public void unregisterInputDeviceListener( InputManagerCompat.InputDeviceListener listener); public void onGenericMotionEvent(MotionEvent event); public void onPause(); public void onResume(); public interface InputDeviceListener { void onInputDeviceAdded(int deviceId); void onInputDeviceChanged(int deviceId); void onInputDeviceRemoved(int deviceId); } ... }
InputManagerCompat
arayüzü aşağıdaki yöntemleri sağlar:
getInputDevice()
- Yansıtma
getInputDevice()
. Oyun kumandasının özelliklerini temsil edenInputDevice
nesnesini elde eder. getInputDeviceIds()
- Yansıtma
getInputDeviceIds()
. Her biri farklı bir giriş cihazının kimliği olan bir tam sayı dizisi döndürür. Bu, birden fazla oyuncuyu destekleyen bir oyun oluşturuyorsanız ve bağlı kaç denetleyicinin bağlı olduğunu tespit etmek istiyorsanız yararlı olur. registerInputDeviceListener()
- Yansıtma
registerInputDeviceListener()
. Yeni bir cihaz eklendiğinde, değiştirildiğinde veya kaldırıldığında bildirim almak için kaydolmanızı sağlar. unregisterInputDeviceListener()
- Yansıtma
unregisterInputDeviceListener()
. Giriş cihazı dinleyicisinin kaydını iptal eder. onGenericMotionEvent()
- Yansıtma
onGenericMotionEvent()
. Oyununuzun, kontrol çubuğu hareketleri ve analog tetikleyici basmaları gibi etkinlikleri temsil edenMotionEvent
nesneleri ve eksen değerlerini engelleyip işlemesini sağlar. onPause()
- Ana etkinlik duraklatıldığında veya oyunda odak kalmadığında oyun kumandası etkinlikleri için yoklamayı durdurur.
onResume()
- Ana etkinlik devam ettirildiğinde veya oyun başlatılıp ön planda çalıştığında oyun denetleyicisi etkinlikleri için yoklamaya başlar.
InputDeviceListener
InputManager.InputDeviceListener
arayüzünü yansıtır. Oyun kumandası eklendiğinde, değiştirildiğinde veya kaldırıldığında bunu size bildirir.
Ardından, InputManagerCompat
için farklı platform sürümlerinde çalışan uygulamalar oluşturun. Oyununuz Android 4.1 veya sonraki bir sürümde çalışıyorsa ve bir InputManagerCompat
yöntemini çağırıyorsa proxy uygulaması, InputManager
içindeki eşdeğer yöntemi çağırır.
Ancak oyununuz, Android 4.0'a kadar Android 3.1 ve 4.0 arasındaki sürümlerde çalışıyorsa özel uygulama, yalnızca Android 3.1'den sonra kullanıma sunulan API'leri kullanarak InputManagerCompat
yöntemlerine yapılan çağrıları işler. Çalışma zamanında hangi sürüme özgü uygulamanın kullanıldığına bakılmaksızın, uygulama, çağrı sonuçlarını şeffaf bir şekilde oyuna geri aktarır.
Arayüzü Android 4.1 ve sonraki sürümlere uygulayın
InputManagerCompatV16
, proxy yönteminin gerçek bir InputManager
ve InputManager.InputDeviceListener
öğesine çağırdığı InputManagerCompat
arayüzünün bir uygulamasıdır. InputManager
, Context
sisteminden elde edilir.
Kotlin
// The InputManagerCompatV16 class is a reference implementation. // The full code is provided in the ControllerSample.zip sample. public class InputManagerV16( context: Context, private val inputManager: InputManager = context.getSystemService(Context.INPUT_SERVICE) as InputManager, private val listeners: MutableMap<InputManager.InputDeviceListener, V16InputDeviceListener> = mutableMapOf() ) : InputManagerCompat { override val inputDeviceIds: IntArray = inputManager.inputDeviceIds override fun getInputDevice(id: Int): InputDevice = inputManager.getInputDevice(id) override fun registerInputDeviceListener( listener: InputManager.InputDeviceListener, handler: Handler? ) { V16InputDeviceListener(listener).also { v16listener -> inputManager.registerInputDeviceListener(v16listener, handler) listeners += listener to v16listener } } // Do the same for unregistering an input device listener ... override fun onGenericMotionEvent(event: MotionEvent) { // unused in V16 } override fun onPause() { // unused in V16 } override fun onResume() { // unused in V16 } } class V16InputDeviceListener( private val idl: InputManager.InputDeviceListener ) : InputManager.InputDeviceListener { override fun onInputDeviceAdded(deviceId: Int) { idl.onInputDeviceAdded(deviceId) } // Do the same for device change and removal ... }
Java
// The InputManagerCompatV16 class is a reference implementation. // The full code is provided in the ControllerSample.zip sample. public class InputManagerV16 implements InputManagerCompat { private final InputManager inputManager; private final Map<InputManagerCompat.InputDeviceListener, V16InputDeviceListener> listeners; public InputManagerV16(Context context) { inputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE); listeners = new HashMap<InputManagerCompat.InputDeviceListener, V16InputDeviceListener>(); } @Override public InputDevice getInputDevice(int id) { return inputManager.getInputDevice(id); } @Override public int[] getInputDeviceIds() { return inputManager.getInputDeviceIds(); } static class V16InputDeviceListener implements InputManager.InputDeviceListener { final InputManagerCompat.InputDeviceListener mIDL; public V16InputDeviceListener(InputDeviceListener idl) { mIDL = idl; } @Override public void onInputDeviceAdded(int deviceId) { mIDL.onInputDeviceAdded(deviceId); } // Do the same for device change and removal ... } @Override public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { V16InputDeviceListener v16Listener = new V16InputDeviceListener(listener); inputManager.registerInputDeviceListener(v16Listener, handler); listeners.put(listener, v16Listener); } // Do the same for unregistering an input device listener ... @Override public void onGenericMotionEvent(MotionEvent event) { // unused in V16 } @Override public void onPause() { // unused in V16 } @Override public void onResume() { // unused in V16 } }
Arayüzü Android 3.1'den Android 4.0'a kadar olan sürümlerde uygulama
Android 3.1'den Android 4.0'a kadarki sürümleri destekleyen bir InputManagerCompat
uygulaması oluşturmak için aşağıdaki nesneleri kullanabilirsiniz:
- Cihaza bağlı oyun kumandalarını izlemek için kullanılan cihaz kimliklerinin
SparseArray
kadarı. - Cihaz etkinliklerini işlemek için bir
Handler
. Bir uygulama başlatıldığında veya devam ettirildiğindeHandler
, oyun kumandasının bağlantısını kesmek için yoklamayı başlatan bir mesaj alır.Handler
, bilinen her bağlı oyun kumandasını kontrol etmek ve bir cihaz kimliği döndürülüp döndürülmediğini görmek için bir döngü başlatır.null
döndürme değeri, oyun kumandasının bağlantısının kesildiğini gösterir.Handler
, uygulama duraklatıldığında yoklamayı durdurur. InputManagerCompat.InputDeviceListener
nesneden birMap
. Takip edilen oyun kumandalarının bağlantı durumunu güncellemek için işleyicileri kullanırsınız.
Kotlin
// The InputManagerCompatV9 class is a reference implementation. // The full code is provided in the ControllerSample.zip sample. class InputManagerV9( val devices: SparseArray<Array<Long>> = SparseArray(), private val listeners: MutableMap<InputManager.InputDeviceListener, Handler> = mutableMapOf() ) : InputManagerCompat { private val defaultHandler: Handler = PollingMessageHandler(this) … }
Java
// The InputManagerCompatV9 class is a reference implementation. // The full code is provided in the ControllerSample.zip sample. public class InputManagerV9 implements InputManagerCompat { private final SparseArray<long[]> devices; private final Map<InputDeviceListener, Handler> listeners; private final Handler defaultHandler; … public InputManagerV9() { devices = new SparseArray<long[]>(); listeners = new HashMap<InputDeviceListener, Handler>(); defaultHandler = new PollingMessageHandler(this); } }
Handler
aralığını genişleten bir PollingMessageHandler
nesnesi uygulayın ve handleMessage()
yöntemini geçersiz kılın. Bu yöntem, ekli bir oyun kumandasının bağlantısının kesilip kesilmediğini kontrol eder ve kayıtlı dinleyicilere bildirim gönderir.
Kotlin
private class PollingMessageHandler( inputManager: InputManagerV9, private val mInputManager: WeakReference<InputManagerV9> = WeakReference(inputManager) ) : Handler() { override fun handleMessage(msg: Message) { super.handleMessage(msg) when (msg.what) { MESSAGE_TEST_FOR_DISCONNECT -> { mInputManager.get()?.also { imv -> val time = SystemClock.elapsedRealtime() val size = imv.devices.size() for (i in 0 until size) { imv.devices.valueAt(i)?.also { lastContact -> if (time - lastContact[0] > CHECK_ELAPSED_TIME) { // check to see if the device has been // disconnected val id = imv.devices.keyAt(i) if (null == InputDevice.getDevice(id)) { // Notify the registered listeners // that the game controller is disconnected imv.devices.remove(id) } else { lastContact[0] = time } } } } sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT, CHECK_ELAPSED_TIME) } } } } }
Java
private static class PollingMessageHandler extends Handler { private final WeakReference<InputManagerV9> inputManager; PollingMessageHandler(InputManagerV9 im) { inputManager = new WeakReference<InputManagerV9>(im); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MESSAGE_TEST_FOR_DISCONNECT: InputManagerV9 imv = inputManager.get(); if (null != imv) { long time = SystemClock.elapsedRealtime(); int size = imv.devices.size(); for (int i = 0; i < size; i++) { long[] lastContact = imv.devices.valueAt(i); if (null != lastContact) { if (time - lastContact[0] > CHECK_ELAPSED_TIME) { // check to see if the device has been // disconnected int id = imv.devices.keyAt(i); if (null == InputDevice.getDevice(id)) { // Notify the registered listeners // that the game controller is disconnected imv.devices.remove(id); } else { lastContact[0] = time; } } } } sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT, CHECK_ELAPSED_TIME); } break; } } }
Oyun kumandasının bağlantısını kesmek için yoklamayı başlatmak ve durdurmak için şu yöntemleri geçersiz kılın:
Kotlin
private const val MESSAGE_TEST_FOR_DISCONNECT = 101 private const val CHECK_ELAPSED_TIME = 3000L class InputManagerV9( val devices: SparseArray<Array<Long>> = SparseArray(), private val listeners: MutableMap<InputManager.InputDeviceListener, Handler> = mutableMapOf() ) : InputManagerCompat { ... override fun onPause() { defaultHandler.removeMessages(MESSAGE_TEST_FOR_DISCONNECT) } override fun onResume() { defaultHandler.sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT, CHECK_ELAPSED_TIME) } ... }
Java
private static final int MESSAGE_TEST_FOR_DISCONNECT = 101; private static final long CHECK_ELAPSED_TIME = 3000L; @Override public void onPause() { defaultHandler.removeMessages(MESSAGE_TEST_FOR_DISCONNECT); } @Override public void onResume() { defaultHandler.sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT, CHECK_ELAPSED_TIME); }
Bir giriş cihazının eklendiğini tespit etmek için onGenericMotionEvent()
yöntemini geçersiz kılın. Sistem bir hareket etkinliği bildirdiğinde, bu etkinliğin önceden izlenen bir cihaz kimliğinden mi yoksa yeni bir cihaz kimliğinden mi geldiğini kontrol edin. Cihaz kimliği yeniyse kayıtlı dinleyicilere bildirin.
Kotlin
override fun onGenericMotionEvent(event: MotionEvent) { // detect new devices val id = event.deviceId val timeArray: Array<Long> = mDevices.get(id) ?: run { // Notify the registered listeners that a game controller is added ... arrayOf<Long>().also { mDevices.put(id, it) } } timeArray[0] = SystemClock.elapsedRealtime() }
Java
@Override public void onGenericMotionEvent(MotionEvent event) { // detect new devices int id = event.getDeviceId(); long[] timeArray = mDevices.get(id); if (null == timeArray) { // Notify the registered listeners that a game controller is added ... timeArray = new long[1]; mDevices.put(id, timeArray); } long time = SystemClock.elapsedRealtime(); timeArray[0] = time; }
İşleyicilerin bildirimi, mesaj sırasına bir DeviceEvent
Runnable
nesnesi göndermek için Handler
nesnesi kullanılarak uygulanır. DeviceEvent
, bir InputManagerCompat.InputDeviceListener
referansını içeriyor. DeviceEvent
çalıştırıldığında, oyun kumandasının eklenmesi, değiştirilmesi veya kaldırılması durumunda sinyal vermek için dinleyicinin uygun geri çağırma yöntemi çağrılır.
Kotlin
class InputManagerV9( val devices: SparseArray<Array<Long>> = SparseArray(), private val listeners: MutableMap<InputManager.InputDeviceListener, Handler> = mutableMapOf() ) : InputManagerCompat { ... override fun registerInputDeviceListener( listener: InputManager.InputDeviceListener, handler: Handler? ) { listeners[listener] = handler ?: defaultHandler } override fun unregisterInputDeviceListener(listener: InputManager.InputDeviceListener) { listeners.remove(listener) } private fun notifyListeners(why: Int, deviceId: Int) { // the state of some device has changed listeners.forEach { listener, handler -> DeviceEvent.getDeviceEvent(why, deviceId, listener).also { handler?.post(it) } } } ... } private val sObjectQueue: Queue<DeviceEvent> = ArrayDeque<DeviceEvent>() private class DeviceEvent( private var mMessageType: Int, private var mId: Int, private var mListener: InputManager.InputDeviceListener ) : Runnable { companion object { fun getDeviceEvent(messageType: Int, id: Int, listener: InputManager.InputDeviceListener) = sObjectQueue.poll()?.apply { mMessageType = messageType mId = id mListener = listener } ?: DeviceEvent(messageType, id, listener) } override fun run() { when(mMessageType) { ON_DEVICE_ADDED -> mListener.onInputDeviceAdded(mId) ON_DEVICE_CHANGED -> mListener.onInputDeviceChanged(mId) ON_DEVICE_REMOVED -> mListener.onInputDeviceChanged(mId) else -> { // Handle unknown message type } } } }
Java
@Override public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { listeners.remove(listener); if (handler == null) { handler = defaultHandler; } listeners.put(listener, handler); } @Override public void unregisterInputDeviceListener(InputDeviceListener listener) { listeners.remove(listener); } private void notifyListeners(int why, int deviceId) { // the state of some device has changed if (!listeners.isEmpty()) { for (InputDeviceListener listener : listeners.keySet()) { Handler handler = listeners.get(listener); DeviceEvent odc = DeviceEvent.getDeviceEvent(why, deviceId, listener); handler.post(odc); } } } private static class DeviceEvent implements Runnable { private int mMessageType; private int mId; private InputDeviceListener mListener; private static Queue<DeviceEvent> sObjectQueue = new ArrayDeque<DeviceEvent>(); ... static DeviceEvent getDeviceEvent(int messageType, int id, InputDeviceListener listener) { DeviceEvent curChanged = sObjectQueue.poll(); if (null == curChanged) { curChanged = new DeviceEvent(); } curChanged.mMessageType = messageType; curChanged.mId = id; curChanged.mListener = listener; return curChanged; } @Override public void run() { switch (mMessageType) { case ON_DEVICE_ADDED: mListener.onInputDeviceAdded(mId); break; case ON_DEVICE_CHANGED: mListener.onInputDeviceChanged(mId); break; case ON_DEVICE_REMOVED: mListener.onInputDeviceRemoved(mId); break; default: // Handle unknown message type ... break; } // Put this runnable back in the queue sObjectQueue.offer(this); } }
Artık iki tane InputManagerCompat
uygulamanız var: Biri Android 4.1 ve sonraki sürümleri çalıştıran cihazlarda, diğeri ise Android 3.1 ile Android 4.0 arasındaki sürümleri çalıştıran cihazlarda çalışan.
Sürüme özgü uygulama kullanın
Sürüme özgü geçiş mantığı, fabrika görevi gören bir sınıfta uygulanır.
Kotlin
object Factory { fun getInputManager(context: Context): InputManagerCompat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { InputManagerV16(context) } else { InputManagerV9() } }
Java
public static class Factory { public static InputManagerCompat getInputManager(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { return new InputManagerV16(context); } else { return new InputManagerV9(); } } }
Artık bir InputManagerCompat
nesnesini örneklendirmek ve ana View
öğenize InputManagerCompat.InputDeviceListener
kaydedebilirsiniz. Ayarladığınız sürüm değiştirme mantığı nedeniyle, oyununuz otomatik olarak cihazın çalıştırdığı Android sürümüne uygun uygulamayı kullanır.
Kotlin
class GameView(context: Context) : View(context), InputManager.InputDeviceListener { private val inputManager: InputManagerCompat = Factory.getInputManager(context).apply { registerInputDeviceListener(this@GameView, null) ... } ... }
Java
public class GameView extends View implements InputDeviceListener { private InputManagerCompat inputManager; ... public GameView(Context context, AttributeSet attrs) { inputManager = InputManagerCompat.Factory.getInputManager(this.getContext()); inputManager.registerInputDeviceListener(this, null); ... } }
Ardından, Oyun Denetleyicisi'nden MotionEvent'i işleme bölümünde açıklandığı gibi ana görünümünüzde onGenericMotionEvent()
yöntemini geçersiz kılın. Oyununuz artık Android 3.1 (API seviyesi 12) ve sonraki sürümleri çalıştıran cihazlarda oyun denetleyicisi etkinliklerini tutarlı şekilde işleyebiliyor.
Kotlin
override fun onGenericMotionEvent(event: MotionEvent): Boolean { inputManager.onGenericMotionEvent(event) // Handle analog input from the controller as normal ... return super.onGenericMotionEvent(event) }
Java
@Override public boolean onGenericMotionEvent(MotionEvent event) { inputManager.onGenericMotionEvent(event); // Handle analog input from the controller as normal ... return super.onGenericMotionEvent(event); }
Bu uyumluluk kodunun eksiksiz bir uygulamasını, yukarıdaki ControllerSample.zip
örneğinde verilen GameView
sınıfında bulabilirsiniz.