Wenn Sie Gamecontroller in Ihrem Spiel unterstützen, liegt es in Ihrer Verantwortung, dafür zu sorgen, dass Ihr Spiel auf Geräten mit verschiedenen Android-Versionen einheitlich auf Controller reagiert. So kann Ihr Spiel ein breiteres Publikum erreichen und Ihre Spieler können mit ihren Controllern nahtlos spielen, auch wenn sie ihre Android-Geräte wechseln oder aktualisieren.
In diesem Kurs wird gezeigt, wie Sie APIs verwenden, die in Android 4.1 und höher verfügbar sind, und zwar auf abwärtskompatible Weise. So kann Ihr Spiel die folgenden Funktionen auf Geräten mit Android 3.1 und höher unterstützen:
- Das Spiel kann erkennen, ob ein neuer Controller hinzugefügt, geändert oder entfernt wird.
- Das Spiel kann die Funktionen eines Controllers abfragen.
- Das Spiel kann eingehende Bewegungsereignisse von einem Controller erkennen.
APIs für die Unterstützung von Gamecontrollern abstrahieren
Angenommen, Sie möchten feststellen können, ob sich der Verbindungsstatus eines Gamecontrollers auf Geräten mit Android 3.1 (API‑Level 12) geändert hat. Die APIs sind jedoch erst ab Android 4.1 (API-Level 16) verfügbar. Sie müssen also eine Implementierung bereitstellen, die Android 4.1 und höher unterstützt, und gleichzeitig einen Fallback-Mechanismus für Android 3.1 bis Android 4.0.
Tabelle 1 enthält die Unterschiede bei der Unterstützung von Gamecontrollern zwischen Android 3.1 (API-Level 12) und 4.1 (API-Level 16). So können Sie leichter entscheiden, für welche Funktionen ein Fallback-Mechanismus für niedrigere Versionen erforderlich ist.
Tabelle 1 APIs zur Unterstützung von Controllern für verschiedene Android-Versionen.
| Informationen zum Verantwortlichen | Controller API | API-Level 12 | API-Level 16 |
|---|---|---|---|
| Geräte-ID | getInputDeviceIds() |
• | |
getInputDevice() |
• | ||
getVibrator() |
• | ||
SOURCE_JOYSTICK |
• | • | |
SOURCE_GAMEPAD |
• | • | |
| Verbindungsstatus | onInputDeviceAdded() |
• | |
onInputDeviceChanged() |
• | ||
onInputDeviceRemoved() |
• | ||
| Erkennung von Eingabeereignissen | D-Pad-Druck (
KEYCODE_DPAD_UP,
KEYCODE_DPAD_DOWN,
KEYCODE_DPAD_LEFT,
KEYCODE_DPAD_RIGHT,
KEYCODE_DPAD_CENTER) |
• | • |
Drücken einer Gamepad-Taste (
BUTTON_A,
BUTTON_B,
BUTTON_THUMBL,
BUTTON_THUMBR,
BUTTON_SELECT,
BUTTON_START,
BUTTON_R1,
BUTTON_L1,
BUTTON_R2,
BUTTON_L2) |
• | • | |
Bewegung von Joystick und Hat Switch (
AXIS_X,
AXIS_Y,
AXIS_Z,
AXIS_RZ,
AXIS_HAT_X,
AXIS_HAT_Y) |
• | • | |
Analoger Triggerdruck (
AXIS_LTRIGGER,
AXIS_RTRIGGER) |
• | • |
Mit Abstraktion können Sie eine versionsabhängige Unterstützung für Gamecontroller erstellen, die plattformübergreifend funktioniert. Dieser Ansatz umfasst die folgenden Schritte:
- Definieren Sie eine Zwischen-Java-Schnittstelle, die die Implementierung der für Ihr Spiel erforderlichen Controllerfunktionen abstrahiert.
- Erstellen Sie eine Proxy-Implementierung Ihrer Schnittstelle, die APIs in Android 4.1 und höher verwendet.
- Erstellen Sie eine benutzerdefinierte Implementierung Ihrer Schnittstelle, die APIs verwendet, die zwischen Android 3.1 und Android 4.0 verfügbar sind.
- Erstelle die Logik für das Umschalten zwischen diesen Implementierungen zur Laufzeit und beginne, die Schnittstelle in deinem Spiel zu verwenden.
Eine Übersicht darüber, wie Abstraktion verwendet werden kann, um zu prüfen, ob Anwendungen abwärtskompatibel mit verschiedenen Android-Versionen funktionieren, finden Sie unter Abwärtskompatible UIs erstellen.
Schnittstelle für Abwärtskompatibilität hinzufügen
Um Abwärtskompatibilität zu gewährleisten, können Sie eine benutzerdefinierte Schnittstelle erstellen und dann versionsspezifische Implementierungen hinzufügen. Ein Vorteil dieses Ansatzes ist, dass Sie die öffentlichen Schnittstellen auf Android 4.1 (API-Level 16) spiegeln können, die Gamecontroller unterstützen.
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);
}
...
}
Die InputManagerCompat-Schnittstelle bietet die folgenden Methoden:
getInputDevice()- Spiegel
getInputDevice(): Ruft dasInputDevice-Objekt ab, das die Funktionen eines Controllers darstellt. getInputDeviceIds()- Spiegel
getInputDeviceIds(): Gibt ein Array von Ganzzahlen zurück, wobei jede Ganzzahl eine ID für ein anderes Eingabegerät ist. Das ist nützlich, wenn Sie ein Spiel entwickeln, das mehrere Spieler unterstützt, und Sie erkennen möchten, wie viele Controller verbunden sind. registerInputDeviceListener()- Spiegel
registerInputDeviceListener(): Ermöglicht die Registrierung, um benachrichtigt zu werden, wenn ein neues Gerät hinzugefügt, geändert oder entfernt wird. unregisterInputDeviceListener()- Spiegel
unregisterInputDeviceListener(): Hebt die Registrierung eines Eingabegerät-Listeners auf. onGenericMotionEvent()- Spiegel
onGenericMotionEvent(): Ermöglicht es Ihrem Spiel,MotionEvent-Objekte und Achsenwerte abzufangen und zu verarbeiten, die Ereignisse wie Joystickbewegungen und analoge Trigger-Betätigungen darstellen. onPause()- Beendet das Abrufen von Gamecontroller-Ereignissen, wenn die Hauptaktivität pausiert wird oder das Spiel nicht mehr im Fokus ist.
onResume()- Beginnt mit dem Abrufen von Gamecontroller-Ereignissen, wenn die Hauptaktivität fortgesetzt wird oder wenn das Spiel gestartet wird und im Vordergrund ausgeführt wird.
InputDeviceListener- Spiegelt die
InputManager.InputDeviceListener-Schnittstelle wider. Informiert Ihr Spiel, wenn ein Controller hinzugefügt, geändert oder entfernt wurde.
Als Nächstes erstellen Sie Implementierungen für InputManagerCompat, die auf verschiedenen Plattformversionen funktionieren. Wenn Ihr Spiel unter Android 4.1 oder höher ausgeführt wird und eine InputManagerCompat-Methode aufruft, ruft die Proxy-Implementierung die entsprechende Methode in InputManager auf.
Wenn Ihr Spiel jedoch unter Android 3.1 bis Android 4.0 ausgeführt wird, verarbeitet die benutzerdefinierte Implementierung Aufrufe von InputManagerCompat-Methoden nur mit APIs, die spätestens in Android 3.1 eingeführt wurden. Unabhängig davon, welche versionsspezifische Implementierung zur Laufzeit verwendet wird, werden die Aufrufergebnisse transparent an das Spiel zurückgegeben.
Schnittstelle auf Android 4.1 und höher implementieren
InputManagerCompatV16 ist eine Implementierung der InputManagerCompat-Schnittstelle, die Methodenaufrufe an eine tatsächliche InputManager und InputManager.InputDeviceListener weiterleitet.
Die InputManager wird vom System Context abgerufen.
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
}
}
Schnittstelle auf Android 3.1 bis Android 4.0 implementieren
Wenn Sie eine Implementierung von InputManagerCompat erstellen möchten, die Android 3.1 bis Android 4.0 unterstützt, können Sie die folgenden Objekte verwenden:
- Eine
SparseArrayvon Geräte-IDs, um die mit dem Gerät verbundenen Controller zu verfolgen. - Ein
Handlerzum Verarbeiten von Geräteereignissen. Wenn eine App gestartet oder fortgesetzt wird, empfängtHandlereine Nachricht, um mit dem Polling nach einer Trennung des Gamecontrollers zu beginnen. MitHandlerwird eine Schleife gestartet, um jeden bekannten verbundenen Gamecontroller zu prüfen und festzustellen, ob eine Geräte-ID zurückgegeben wird. Ein Rückgabewert vonnullgibt an, dass der Controller getrennt ist. DieHandlerwird nicht mehr abgefragt, wenn die App pausiert wird. Ein
MapvonInputManagerCompat.InputDeviceListener-Objekten. Sie verwenden die Listener, um den Verbindungsstatus der verfolgten Gamecontroller zu aktualisieren.
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);
}
}
Implementieren Sie ein PollingMessageHandler-Objekt, das Handler erweitert, und überschreiben Sie die Methode handleMessage(). Mit dieser Methode wird geprüft, ob ein angeschlossener Controller getrennt wurde. Registrierte Listener werden benachrichtigt.
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;
}
}
}
Wenn Sie das Polling für die Trennung des Gamecontrollers starten und beenden möchten, überschreiben Sie diese Methoden:
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);
}
Wenn Sie erkennen möchten, dass ein Eingabegerät hinzugefügt wurde, überschreiben Sie die Methode onGenericMotionEvent(). Wenn das System ein Bewegungsereignis meldet, prüfen Sie, ob es von einer Geräte-ID stammt, die bereits erfasst wird, oder von einer neuen Geräte-ID. Wenn die Geräte-ID neu ist, benachrichtigen Sie registrierte Listener.
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;
}
Die Benachrichtigung von Listenern wird durch die Verwendung des Handler-Objekts implementiert, um ein DeviceEvent-Runnable-Objekt an die Nachrichtenwarteschlange zu senden.
DeviceEvent enthält einen Verweis auf ein InputManagerCompat.InputDeviceListener. Wenn DeviceEvent ausgeführt wird, wird die entsprechende Callback-Methode des Listeners aufgerufen, um zu signalisieren, ob der Gamecontroller hinzugefügt, geändert oder entfernt wurde.
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);
}
}
Sie haben jetzt zwei Implementierungen von InputManagerCompat: eine für Geräte mit Android 4.1 und höher und eine für Geräte mit Android 3.1 bis Android 4.0.
Versionsspezifische Implementierung verwenden
Die versionsspezifische Umschaltlogik wird in einer Klasse implementiert, die als Factory fungiert.
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();
}
}
}
Jetzt können Sie ein InputManagerCompat-Objekt instanziieren und ein InputManagerCompat.InputDeviceListener in Ihrem Haupt-View registrieren. Dank der von Ihnen eingerichteten Logik für den Versionswechsel wird in Ihrem Spiel automatisch die Implementierung verwendet, die für die Android-Version des Geräts geeignet ist.
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);
...
}
}
Überschreiben Sie als Nächstes die Methode onGenericMotionEvent() in Ihrer Hauptansicht, wie in MotionEvent von einem Gamecontroller verarbeiten (und höher) beschrieben. Ihr Spiel sollte jetzt in der Lage sein, Controller-Ereignisse auf Geräten mit Android 3.1 (API-Level) konsistent zu verarbeiten.
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);
}
Eine vollständige Implementierung dieses Kompatibilitätscodes finden Sie in der Klasse GameView, die im Beispiel ControllerSample.zip zum Herunterladen bereitgestellt wird.