Mauseingabe

In diesem Artikel erfahren Sie, wie Sie Mauseingaben für Google Play Spiele auf dem PC für Spiele implementieren, bei denen der Modus für die Eingabeübersetzung nicht ideal ist.

PC-Spieler haben normalerweise eine Tastatur und Maus anstelle eines Touchscreens. Daher ist es wichtig zu überlegen, ob Ihr Spiel Mauseingaben unterstützt. Standardmäßig wandelt Google Play Spiele auf dem PC jedes Ereignis mit der linken Maustaste in ein einzelnes virtuelles Tippereignis um. Dies wird als „Eingabeübersetzungsmodus“ bezeichnet.

Auch wenn dieser Modus mit nur wenigen Änderungen funktioniert, bietet er PC-Spielern kein natives Erlebnis. Dazu empfehlen wir, Folgendes zu implementieren:

  • Hover-Status für Kontextmenüs anstelle von Drücken und Halten von Aktionen
  • Mit der rechten Maustaste kannst du alternative Aktionen ausführen, die durch langes Drücken oder in einem Kontextmenü ausgeführt werden.
  • Mouselook für First- oder Third-Person-Actionspiele anstelle von Presse- und Drag-Events

Zur Unterstützung von UI-Mustern, die auf PCs üblich sind, müssen Sie den Modus für die Eingabeübersetzung deaktivieren.

Die Eingabeverarbeitung für Google Play Spiele auf dem PC ist mit der von ChromeOS identisch. Durch die Änderungen zur Unterstützung von PCs wird dein Spiel für alle Android-Spieler verbessert.

Modus für die Eingabeübersetzung deaktivieren

Deklarieren Sie in der Datei AndroidManifest.xml die Funktion android.hardware.type.pc. Dies bedeutet, dass Ihr Spiel PC-Hardware verwendet und der Eingabeübersetzungsmodus deaktiviert ist. Wenn Sie required="false" hinzufügen, kann Ihr Spiel auch ohne Maus auf Smartphones und Tablets installiert werden. Beispiele:

<manifest ...>
  <uses-feature
      android:name="android.hardware.type.pc"
      android:required="false" />
  ...
</manifest>

Die Produktionsversion von Google Play Spiele auf dem PC wechselt beim Start eines Spiels in den richtigen Modus. Wenn Sie es im Entwickleremulator ausführen, müssen Sie mit der rechten Maustaste auf das Symbol in der Taskleiste klicken, Developer Options (Entwickleroptionen) und dann PC mode(KiwiMouse) (PC-Modus (KiwiMouse)) auswählen, um die Mauseingabe im Rohformat zu erhalten.

Screenshot des im Kontextmenü ausgewählten „PC mode(KiwiMouse)“

Danach wird die Mausbewegung von View.onGenericMotionEvent gemeldet. Die Quelle SOURCE_MOUSE weist darauf hin, 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 zur Handhabung von Mauseingaben finden Sie in der ChromeOS-Dokumentation.

Mausbewegungen steuern

Zum Erkennen von Mausbewegungen warten Sie auf die Ereignisse ACTION_HOVER_ENTER, ACTION_HOVER_EXIT und ACTION_HOVER_MOVE.

Diese Methode eignet sich am besten, um zu erkennen, wie Nutzer in einem Spiel über Schaltflächen oder Objekte fahren. So haben Sie die Möglichkeit, ein Hinweisfeld anzuzeigen oder einen Mouseover-Zustand zu implementieren, um hervorzuheben, was ein Spieler auswählen wird. Beispiele:

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

Umgang mit Mausklicks

PCs haben schon lange sowohl die linke als auch die rechte Maustaste und ermöglichen interaktive Elemente sowohl primäre als auch sekundäre Aktionen. In einem Spiel eignen sich Tippaktionen wie das Tippen auf eine Schaltfläche am besten dem Linksklick, wenn sich Aktionen durch Berühren und Halten beim Rechtsklick am natürlichsten anfühlen. In Echtzeit-Strategiespielen können Sie sie auch mit der linken Maustaste auswählen und mit der rechten Ego-Shooter können ein primäres und sekundäres Feuer nach links und einen Rechtsklick zuweisen. Bei unendlichen Läufern wird zum Beispiel mit der linken Maustaste springen und mit der rechten Das Ereignis des mittleren Klicks wird nicht unterstützt.

Wenn du das Drücken von Tasten steuern möchtest, verwende ACTION_DOWN und ACTION_UP. Verwenden Sie dann getActionButton, um festzustellen, welche Schaltfläche die Aktion ausgelöst hat, oder getButtonState, um den Status aller Schaltflächen abzurufen.

In diesem Beispiel wird eine Aufzählung 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 Mausrad

Wir empfehlen, das Scrollrad der Maus zu verwenden, anstatt sie auseinander- und zusammenzuziehen, um Touch-Gesten zu zoomen oder Scrollbereiche in Ihrem Spiel zu berühren und zu ziehen.

Warten Sie auf das Ereignis ACTION_SCROLL, um Werte für das Scrollrad zu lesen. Das Delta seit dem letzten Frame kann mithilfe von getAxisValue mit AXIS_VSCROLL für den vertikalen Versatz und AXIS_HSCROLL für den horizontalen Versatz abgerufen werden. Beispiele:

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 Cursor vollständig gesteuert werden, z. B. in Ego- oder Third-Person-Action-Spielen, bei denen Mausbewegungen Kamerabewegungen zugeordnet werden. Rufen Sie View.requestPointerCapture() auf, um die ausschließliche Kontrolle über die Maus zu übernehmen.

requestPointerCapture() funktioniert nur, wenn die Ansichtshierarchie, die Ihre Ansicht enthält, im Fokus liegt. Aus diesem Grund können Sie die Zeigererfassung nicht im onCreate-Callback abrufen. Sie sollten entweder auf eine Spielerinteraktion warten, um den Mauszeiger zu erfassen, z. B. bei der Interaktion mit dem Hauptmenü, oder Sie verwenden den onWindowFocusChanged-Callback. Beispiele:

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 weitergeleitet, in der OnCapturedPointerListener registriert wurde. Beispiele:

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

Wenn Sie eine exklusive Mausaufnahme freigeben möchten, z. B. um Spielern die Interaktion mit einem Pausenmenü zu ermöglichen, rufen Sie View.releasePointerCapture() auf.