Questo argomento spiega come implementare l'input del mouse per Google Play Giochi su PC per i giochi in cui la modalità di traduzione dell'input non offre un'esperienza di gioco ideale.
I giocatori su PC in genere hanno una tastiera e un mouse anziché un touchscreen, quindi è importante valutare se il tuo gioco supporta l'input del mouse. Per impostazione predefinita, Google Play Giochi su PC converte qualsiasi evento del mouse con clic sinistro in un singolo evento di tocco virtuale. Questa modalità è nota come "modalità di traduzione dell'input".
Sebbene questa modalità renda il tuo gioco funzionale con poche modifiche, non offre ai giocatori su PC un'esperienza che sembri nativa. Per questo motivo, ti consigliamo di implementare quanto segue:
- Stati di passaggio del mouse per i menu contestuali anziché azioni di pressione prolungata
- Clic con il tasto destro per azioni alternative che si verificano con una pressione prolungata o in un menu contestuale
- Visualizzazione con il mouse per i giochi d'azione in prima o terza persona anziché un evento di pressione e trascinamento
Per supportare i pattern dell'interfaccia utente comuni sui PC, devi disattivare la modalità di traduzione dell'input.
La gestione dell'input per Google Play Giochi su PC è identica a quella di ChromeOS. Le modifiche che supportano i PC migliorano il tuo gioco anche per tutti i giocatori Android.
Disattivare la modalità di traduzione dell'input
Nel file AndroidManifest.xml,
dichiara la
android.hardware.type.pc funzionalità.
Questo indica che il tuo gioco utilizza l'hardware del PC e disattiva la modalità di traduzione dell'input. Inoltre, l'aggiunta di required="false" contribuisce a garantire che il gioco possa essere
installato su smartphone e tablet senza mouse. Ad esempio:
<manifest ...>
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
...
</manifest>
La versione di produzione di Google Play Giochi su PC passa alla modalità corretta all'avvio di un gioco. Quando esegui l'emulatore per sviluppatori, devi fare clic con il tasto destro del mouse sull'icona della barra delle applicazioni, selezionare Opzioni sviluppatore e poi Modalità PC(KiwiMouse) per ricevere l'input del mouse non elaborato.
Dopodiché, il movimento del mouse viene segnalato da View.onGenericMotionEvent con l'origine SOURCE_MOUSE
che indica che si tratta di un evento del mouse.
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; });
Per informazioni dettagliate sulla gestione dell'input del mouse, consulta la documentazione di ChromeOS.
Gestire il movimento del mouse
Per rilevare il movimento del mouse, ascolta gli ACTION_HOVER_ENTER, ACTION_HOVER_EXIT e
ACTION_HOVER_MOVE
eventi.
Questa opzione è ideale per rilevare quando l'utente passa il mouse sopra pulsanti o oggetti in un gioco, dandoti la possibilità di visualizzare una casella di suggerimento o implementare uno stato di passaggio del mouse per evidenziare ciò che un giocatore sta per selezionare. Ad esempio:
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; });
Gestire i pulsanti del mouse
I PC hanno da tempo sia il pulsante sinistro che quello destro del mouse, il che conferisce agli elementi interattivi azioni primarie e secondarie. In un gioco, le azioni di tocco, come toccare un pulsante, vengono mappate al meglio al clic sinistro, mentre le azioni di tocco e pressione prolungata risultano più naturali con il clic destro. Nei giochi di strategia in tempo reale puoi anche utilizzare il clic sinistro per selezionare e il clic destro per spostare. Gli sparatutto in prima persona potrebbero assegnare il fuoco primario e secondario al clic sinistro e destro. Un runner infinito potrebbe utilizzare il clic sinistro per saltare e il clic destro per scattare. Non abbiamo aggiunto il supporto per l'evento di clic centrale.
Per gestire le pressioni dei pulsanti, utilizza ACTION_DOWN e ACTION_UP. Poi utilizza getActionButton per determinare quale pulsante ha attivato l'azione o getButtonState per ottenere lo stato di tutti i pulsanti.
In questo esempio, viene utilizzato un enum per visualizzare il risultato di getActionButton:
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 questo esempio, l'azione viene gestita in modo simile agli eventi di passaggio del mouse:
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; });
Gestire lo scorrimento della rotellina del mouse
Ti consigliamo di utilizzare la rotellina del mouse al posto dei gesti di pizzicamento per lo zoom o delle aree di scorrimento con tocco e trascinamento nel gioco.
Per leggere i valori della rotellina di scorrimento, ascolta l'evento ACTION_SCROLL. Il delta dall'ultimo frame può essere recuperato utilizzando getAxisValue con AXIS_VSCROLL per l'offset verticale e AXIS_HSCROLL per l'offset orizzontale. Ad esempio:
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; });
Acquisire l'input del mouse
Alcuni giochi devono assumere il controllo completo del cursore del mouse, ad esempio i giochi d'azione in prima o terza persona che mappano il movimento del mouse al movimento della telecamera. Per assumere il controllo
esclusivo del mouse, richiama View.requestPointerCapture().
requestPointerCapture() funziona solo quando la gerarchia di oggetti View contenente la visualizzazione ha lo stato attivo. Per questo motivo, non puoi acquisire l'acquisizione del puntatore nel callback onCreate. Devi attendere l'interazione del giocatore per acquisire
il puntatore del mouse, ad esempio quando interagisce con il menu principale, oppure utilizzare il
onWindowFocusChanged
callback. Ad esempio:
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(); } }
Gli eventi acquisiti da requestPointerCapture()
vengono inviati alla visualizzazione con stato attivo che ha registrato
OnCapturedPointerListener. Ad esempio:
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; });
Per rilasciare l'acquisizione esclusiva del mouse, ad esempio per consentire ai giocatori di
interagire con un menu di pausa, richiama View.releasePointerCapture().