Questo argomento spiega come implementare l'input del mouse in Google Play Giochi su PC per i giochi in cui la modalità di immissione non offre un'esperienza ideale per i giocatori.
I giocatori su PC di solito hanno una tastiera e un mouse anziché un touchscreen, pertanto è importante valutare se il gioco supporta l'input del mouse. Per impostazione predefinita, Google Play Giochi su PC converte qualsiasi evento di clic con il tasto sinistro del mouse in un singolo evento di tocco virtuale. Questa modalità è nota come "modalità di traduzione dell'input".
Sebbene questa modalità renda il gioco funzionante con poche modifiche, non offre ai giocatori su PC un'esperienza nativa. A questo scopo, ti consigliamo di implementare quanto segue:
- Stati del passaggio del mouse per i menu contestuali anziché le azioni di pressione e pressione
- Fai clic con il tasto destro del mouse per azioni alternative eseguite in caso di pressione prolungata o in un menu contestuale
- Cerca giochi d'azione in prima o terza persona invece di un evento di stampa e trascinamento
Per supportare i pattern UI comuni sui PC, devi disattivare la modalità di traduzione dell'input.
La gestione dell'immissione per Google Play Giochi su PC è identica a quella di ChromeOS. Le modifiche che supportano i PC migliorano anche il gioco per tutti i giocatori Android.
Disattiva la modalità di traduzione dell'input
Nel file AndroidManifest.xml
, dichiara la funzionalità android.hardware.type.pc
.
Questo indica che il gioco utilizza l'hardware del PC e disabilita la modalità di traduzione input. Inoltre, l'aggiunta di required="false"
consente di continuare a installare il gioco su telefoni e tablet senza mouse. Ecco alcuni esempi:
<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 utilizzi l'emulatore sviluppatore, devi fare clic con il tasto destro del mouse sull'icona della barra delle applicazioni, selezionare Opzioni sviluppatore e quindi Modalità PC(KiwiMouse) per ricevere input non elaborati del mouse.
Dopo aver eseguito questa operazione, il movimento del mouse viene riportato 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 maggiori dettagli sulla gestione dell'input del mouse, consulta la documentazione di ChromeOS.
Gestione dei movimenti del mouse
Per rilevare il movimento del mouse, ascolta gli eventi ACTION_HOVER_ENTER
, ACTION_HOVER_EXIT
e ACTION_HOVER_MOVE
.
Questa funzionalità è utile per rilevare l'utente che passa il mouse sopra pulsanti o oggetti in un gioco, offrendoti la possibilità di visualizzare una finestra di suggerimenti o implementare uno stato mouseover per evidenziare ciò che un giocatore sta per selezionare. Ecco alcuni esempi:
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; });
Gestione dei pulsanti del mouse
I PC utilizzano da tempo sia i pulsanti sinistro che destro del mouse, assegnando agli elementi interattivi azioni primarie e secondarie. In un gioco, le azioni di tocco come toccare un pulsante sono più adatte al clic con il tasto sinistro del mouse, dove le azioni di tocco e pressione risultano più naturali con il clic destro. Nei giochi di strategia in tempo reale potresti anche usare il clic con il tasto sinistro per selezionare e il clic con il tasto destro del mouse per spostarti. I tiratori in prima persona possono assegnare il fuoco principale e secondario a sinistra e al clic destro. Un runner infinito potrebbe usare il clic con il tasto sinistro per saltare e il clic con il tasto destro del mouse per passare al trattino. Non abbiamo aggiunto il supporto per l'evento del clic centrale.
Per gestire la pressione dei pulsanti, usa ACTION_DOWN
e ACTION_UP
. Quindi utilizza
getActionButton
per determinare quale pulsante ha attivato l'azione o
getButtonState
per visualizzare lo stato di tutti i pulsanti.
In questo esempio, viene utilizzata un'enumerazione 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 con la rotellina del mouse
Ti consigliamo di utilizzare la rotellina di scorrimento del mouse anziché pizzicare per eseguire lo zoom dei gesti o toccare e trascinare aree di scorrimento nel gioco.
Per leggere i valori della rotellina di scorrimento, esamina l'evento ACTION_SCROLL
. Il parametro delta poiché l'ultimo frame può essere recuperato utilizzando getAxisValue
con AXIS_VSCROLL
per l'offset verticale e AXIS_HSCROLL
per l'offset orizzontale. Ecco alcuni esempi:
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; });
Acquisisci input del mouse
Alcuni giochi devono avere il pieno controllo del cursore del mouse, come i giochi d'azione in prima o terza persona che mappano il movimento del mouse a quello della videocamera. Per assumere
il controllo esclusivo del mouse, richiama View.requestPointerCapture()
.
requestPointerCapture()
funziona solo quando lo stato attivo è impostato sulla gerarchia delle viste
che contiene la vista. Per questo motivo, non puoi acquisire l'acquisizione del puntatore nel callback onCreate
. Devi attendere che l'interazione del player acquisisca il puntatore del mouse, ad esempio durante l'interazione con il menu principale, oppure utilizzare il callback onWindowFocusChanged
. Ecco alcuni esempi:
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 attivabile che ha registrato OnCapturedPointerListener
. Ecco alcuni esempi:
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()
.