In diesem Artikel wird beschrieben, wie die Mauseingabe für Google Play Spiele auf dem PC für Spiele implementiert wird, bei denen der Eingabeübersetzungsmodus kein ideales Spielererlebnis bietet.
PC-Spieler haben in der Regel eine Tastatur und eine Maus, keinen Touchscreen. Daher ist es wichtig, zu überlegen, ob Ihr Spiel die Mauseingabe unterstützt. Standardmäßig wandelt Google Play Spiele auf dem PC jedes Mausklickereignis mit der linken Maustaste in ein einzelnes virtuelles Tippen-Ereignis um. Dies wird als „Eingabeübersetzungsmodus“ bezeichnet.
In diesem Modus ist Ihr Spiel zwar mit wenigen Änderungen funktionsfähig, bietet aber keinen nativen Look für PC-Spieler. Dazu empfehlen wir Folgendes:
- Hover-Zustände für Kontextmenüs, anstatt Aktionen durch Gedrückthalten gedrückt zu halten
- Klicken Sie mit der rechten Maustaste, um alternative Aktionen aufzurufen, die beim langen Drücken oder in einem Kontextmenü ausgeführt werden.
- Mauslook für Actionspiele aus der Ego- oder Third-Person-Perspektive anstelle eines Drücken-und-Ziehen-Ereignisses
Zur Unterstützung von auf PCs gängigen UI-Mustern müssen Sie den Eingabeübersetzungsmodus deaktivieren.
Die Eingabebehandlung für Google Play Spiele auf dem PC entspricht der von ChromeOS. Die Änderungen, die die Unterstützung von PCs ermöglichen, verbessern Ihr Spiel auch für alle Android-Nutzer.
Übersetzungsmodus für die Eingabe deaktivieren
Deklarieren Sie in der Datei AndroidManifest.xml
die android.hardware.type.pc
-Funktion.
Das bedeutet, dass Ihr Spiel PC-Hardware verwendet und der Modus für die Eingabeübersetzung deaktiviert ist. Außerdem kann Ihr Spiel so auch auf Smartphones und Tablets ohne Maus installiert werden.required="false"
Beispiel:
<manifest ...>
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
...
</manifest>
Die Produktionsversion von Google Play Spiele auf dem PC wechselt beim Starten eines Spiels in den richtigen Modus. Wenn Sie den Entwickleremulator verwenden, müssen Sie mit der rechten Maustaste auf das Symbol in der Taskleiste klicken, Entwickleroptionen und dann PC-Modus(KiwiMouse) auswählen, um die Rohmauseingaben zu erhalten.
Danach wird die Mausbewegung von View.onGenericMotionEvent mit der Quelle SOURCE_MOUSE
gemeldet, um anzugeben, dass es sich um ein Mausereignis handelt.
Kotlin
gameView.setOnGenericMotionListener { _, motionEvent -> var handled = false if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // handle the mouse event here handled = true } handled }
Java
gameView.setOnGenericMotionListener((view, motionEvent) -> { if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // handle the mouse event here return true; } return false; });
Weitere Informationen zum Umgang mit der Mauseingabe finden Sie in der ChromeOS-Dokumentation.
Mausbewegungen verarbeiten
Warten Sie zum Erkennen von Mausbewegungen die Ereignisse ACTION_HOVER_ENTER
, ACTION_HOVER_EXIT
und ACTION_HOVER_MOVE
.
Diese Funktion eignet sich am besten, um zu erkennen, wenn der Nutzer den Mauszeiger auf Schaltflächen oder Objekte in einem Spiel bewegt. So können Sie ein Hinweisfeld anzeigen oder einen Mauszeigerstatus implementieren, um hervorzuheben, was ein Spieler auswählen wird. Beispiel:
Kotlin
gameView.setOnGenericMotionListener { _, motionEvent -> var handled = false if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { when(motionEvent.action) { MotionEvent.ACTION_HOVER_ENTER -> Log.d("MA", "Mouse entered at ${motionEvent.x}, ${motionEvent.y}") MotionEvent.ACTION_HOVER_EXIT -> Log.d("MA", "Mouse exited at ${motionEvent.x}, ${motionEvent.y}") MotionEvent.ACTION_HOVER_MOVE -> Log.d("MA", "Mouse hovered at ${motionEvent.x}, ${motionEvent.y}") } handled = true } handled }
Java
gameView.setOnGenericMotionListener((view, motionEvent) -> { if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_HOVER_ENTER: Log.d("MA", "Mouse entered at " + motionEvent.getX() + ", " + motionEvent.getY()); break; case MotionEvent.ACTION_HOVER_EXIT: Log.d("MA", "Mouse exited at " + motionEvent.getX() + ", " + motionEvent.getY()); break; case MotionEvent.ACTION_HOVER_MOVE: Log.d("MA", "Mouse hovered at " + motionEvent.getX() + ", " + motionEvent.getY()); break; } return true; } return false; });
Maustasten handhaben
PCs haben seit langem sowohl die linke als auch die rechte Maustaste, sodass interaktive Elemente sowohl primäre als auch sekundäre Aktionen haben. In einem Spiel sollten Tippaktionen wie das Tippen auf eine Schaltfläche dem Linksklick zugeordnet werden, während Aktionen wie „Tippen und halten“ am besten mit dem Rechtsklick ausgeführt werden. In Echtzeit-Strategiespielen können Sie auch mit der linken Maustaste auswählen und mit der rechten Maustaste bewegen. In Ego-Shootern werden die primäre und sekundäre Schussabgabe möglicherweise der linken und rechten Maustaste zugewiesen. Ein unendlicher Runner könnte mit Linksklick springen und Rechtsklick zum Springen. Das Ereignis „Mitte klicken“ wird nicht unterstützt.
Verwenden Sie ACTION_DOWN
und ACTION_UP
, um Tastendrücke zu verarbeiten. Verwenden Sie dann getActionButton
, um zu ermitteln, welche Schaltfläche die Aktion ausgelöst hat, oder getButtonState
, um den Status aller Schaltflächen abzurufen.
In diesem Beispiel wird ein Enum verwendet, um das Ergebnis von getActionButton
anzuzeigen:
Kotlin
enum class MouseButton { LEFT, RIGHT, UNKNOWN; companion object { fun fromMotionEvent(motionEvent: MotionEvent): MouseButton { return when (motionEvent.actionButton) { MotionEvent.BUTTON_PRIMARY -> LEFT MotionEvent.BUTTON_SECONDARY -> RIGHT else -> UNKNOWN } } } }
Java
enum MouseButton { LEFT, RIGHT, MIDDLE, UNKNOWN; static MouseButton fromMotionEvent(MotionEvent motionEvent) { switch (motionEvent.getActionButton()) { case MotionEvent.BUTTON_PRIMARY: return MouseButton.LEFT; case MotionEvent.BUTTON_SECONDARY: return MouseButton.RIGHT; default: return MouseButton.UNKNOWN; } } }
In diesem Beispiel wird die Aktion ähnlich wie die Hover-Ereignisse behandelt:
Kotlin
// Handle the generic motion event gameView.setOnGenericMotionListener { _, motionEvent -> var handled = false if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { when (motionEvent.action) { MotionEvent.ACTION_BUTTON_PRESS -> Log.d( "MA", "${MouseButton.fromMotionEvent(motionEvent)} pressed at ${motionEvent.x}, ${motionEvent.y}" ) MotionEvent.ACTION_BUTTON_RELEASE -> Log.d( "MA", "${MouseButton.fromMotionEvent(motionEvent)} released at ${motionEvent.x}, ${motionEvent.y}" ) } handled = true } handled }
Java
gameView.setOnGenericMotionListener((view, motionEvent) -> { if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_BUTTON_PRESS: Log.d("MA", MouseButton.fromMotionEvent(motionEvent) + " pressed at " + motionEvent.getX() + ", " + motionEvent.getY()); break; case MotionEvent.ACTION_BUTTON_RELEASE: Log.d("MA", MouseButton.fromMotionEvent(motionEvent) + " released at " + motionEvent.getX() + ", " + motionEvent.getY()); break; } return true; } return false; });
Scrollen mit dem Mausrad verarbeiten
Wir empfehlen, zum Zoomen das Scrollrad der Maus anstelle von Auseinander- und Zusammenziehen der Finger zu verwenden oder Scrollbereiche in Ihrem Spiel zu berühren und zu ziehen.
Zum Lesen der Scrollrad-Werte warten Sie auf das ACTION_SCROLL
-Ereignis. Das Delta seit dem letzten Frame kann mit getAxisValue
mit AXIS_VSCROLL
für den vertikalen Versatz und AXIS_HSCROLL
für den horizontalen Versatz abgerufen werden. Beispiel:
Kotlin
gameView.setOnGenericMotionListener { _, motionEvent -> var handled = false if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { when (motionEvent.action) { MotionEvent.ACTION_SCROLL -> { val scrollX = motionEvent.getAxisValue(MotionEvent.AXIS_HSCROLL) val scrollY = motionEvent.getAxisValue(MotionEvent.AXIS_VSCROLL) Log.d("MA", "Mouse scrolled $scrollX, $scrollY") } } handled = true } handled }
Java
gameView.setOnGenericMotionListener((view, motionEvent) -> { if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_SCROLL: float scrollX = motionEvent.getAxisValue(MotionEvent.AXIS_HSCROLL); float scrollY = motionEvent.getAxisValue(MotionEvent.AXIS_VSCROLL); Log.d("MA", "Mouse scrolled " + scrollX + ", " + scrollY); break; } return true; } return false; });
Mauseingabe erfassen
Bei einigen Spielen muss der Mauszeiger vollständig übernommen werden, z. B. bei Actionspielen in der ersten oder dritten Person, bei denen die Mausbewegung der Kamerabewegung zugeordnet wird. Wenn Sie die Maus exklusiv steuern möchten, drücken Sie View.requestPointerCapture()
.
requestPointerCapture()
funktioniert nur, wenn die Ansichtshierarchie, die Ihre Ansicht enthält, hervorgehoben ist. Aus diesem Grund können Sie im onCreate
-Callback keine Zeigererfassung abrufen. Du solltest entweder auf eine Spielerinteraktion warten, um den Mauszeiger zu erfassen, z. B. bei der Interaktion mit dem Hauptmenü, oder den Callback onWindowFocusChanged
verwenden. Beispiel:
Kotlin
override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) if (hasFocus) { gameView.requestPointerCapture() } }
Java
@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { View gameView = findViewById(R.id.game_view); gameView.requestPointerCapture(); } }
Von requestPointerCapture()
erfasste Ereignisse werden an die fokussierbare Ansicht gesendet, die OnCapturedPointerListener
registriert hat. Beispiel:
Kotlin
gameView.focusable = View.FOCUSABLE gameView.setOnCapturedPointerListener { _, motionEvent -> Log.d("MA", "${motionEvent.x}, ${motionEvent.y}, ${motionEvent.actionButton}") true }
Java
gameView.setFocusable(true); gameView.setOnCapturedPointerListener((view, motionEvent) -> { Log.d("MA", motionEvent.getX() + ", " + motionEvent.getY() + ", " + motionEvent.getActionButton()); return true; });
Rufe View.releasePointerCapture()
auf, um die exklusive Mausaufnahme zu veröffentlichen, damit Spieler beispielsweise mit einem Pausenmenü interagieren können.