Input del mouse

Questo argomento spiega come implementare l'input del mouse per Google Play Giochi su PC per in cui la modalità di traduzione di input non offre un'esperienza di gioco ideale.

I lettori per PC di solito hanno una tastiera e un mouse anziché un touchscreen, il che rende è importante valutare se il gioco supporta l'input del mouse. Per impostazione predefinita, Google Play Giochi su PC converte qualsiasi evento fatto con il clic del mouse con il tasto sinistro del mouse in un singolo un evento di tocco virtuale. Questa è nota come "modalità di traduzione input".

Questa modalità rende il gioco funzionante con poche modifiche, offrono ai giocatori su PC un'esperienza nativa. A questo scopo, ti consigliamo di implementare quanto segue:

  • Stati al passaggio del mouse per i menu contestuali anziché azioni di pressione prolungata
  • Fai clic con il tasto destro del mouse per visualizzare le azioni alternative che si verificano alla pressione prolungata o in un contesto menu
  • Ricerca con il mouse per giochi d'azione in prima o in terza persona anziché per la ricerca con il mouse evento di trascinamento

Per supportare i pattern UI comuni su PC, devi disabilitare l'input modalità di traduzione.

La gestione dell'input per Google Play Giochi su PC è identica a quella ChromeOS I cambiamenti che supportano anche i PC migliorare il gioco per tutti i giocatori Android.

Disattiva modalità di traduzione di input

Nel file AndroidManifest.xml, dichiara il android.hardware.type.pc funzionalità. Questo indica che il gioco utilizza hardware del PC e disattiva la traduzione dell'input . Inoltre, l'aggiunta di required="false" contribuisce a garantire che il tuo gioco possa essere comunque installata su telefoni 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 versione corretta all'avvio di un gioco. Quando l'emulatore di sviluppatori è in esecuzione, devi Fai clic con il tasto destro del mouse sull'icona della barra delle applicazioni, seleziona Opzioni sviluppatore e poi Modalità PC(KiwiMouse) per ricevere input del mouse non elaborato.

Screenshot della &quot;Modalità PC(KiwiMouse)&quot; selezionato nel menu contestuale

Dopodiché, il movimento del mouse viene segnalato da View.onGenericMotionEvent con origine SOURCE_MOUSE a indicare che si tratta di un evento 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 Documentazione di ChromeOS.

Gestione del movimento del mouse

Per rilevare il movimento del mouse, ascolta ACTION_HOVER_ENTER, ACTION_HOVER_EXIT e ACTION_HOVER_MOVE eventi.

Questa funzionalità è particolarmente utile per rilevare che l'utente passa il mouse sopra pulsanti o oggetti in una che offre la possibilità di visualizzare una casella di suggerimento o di implementare uno stato mouseover 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;
});

Gestione dei pulsanti del mouse

I PC dispongono da molto tempo dei pulsanti sinistro e destro del mouse, che offrono elementi interattivi sia le azioni principali che quelle secondarie. In un gioco, puoi toccare delle azioni come toccare un vengono mappati al clic con il tasto sinistro, nel punto in cui tocca e le azioni di sospensione sono più determinanti naturale con il clic con il tasto destro del mouse. Nei giochi di strategia in tempo reale potresti usare fai clic con il tasto sinistro del mouse per selezionare e fai clic con il tasto destro del mouse per spostare. Gli sparatutto in prima persona potrebbero assegnare clic con il tasto destro del mouse o dell'incendio principale e secondario. Un runner infinito potrebbe usa il clic con il tasto sinistro del mouse per saltare e il clic con il tasto destro del mouse per scorrere. Non abbiamo aggiunto il supporto per l'evento di 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 oppure getButtonState per conoscere lo stato di tutti i pulsanti.

In questo esempio, viene utilizzata un'enumerazione per visualizzare il risultato 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;
});

Gestisci lo scorrimento della rotellina del mouse

Ti consigliamo di utilizzare la rotellina di scorrimento del mouse anziché pizzicare per eseguire lo zoom gesti o tocca e trascina le aree di scorrimento nel gioco.

Per leggere i valori della rotellina di scorrimento, esamina l'evento ACTION_SCROLL. Il delta poiché l'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;
});

Acquisisci input del mouse

Alcuni giochi devono assumere il pieno controllo del cursore del mouse, ad esempio il primo o il terzo giochi d'azione con persone che mappano il movimento del mouse al movimento della videocamera. Per controllo esclusivo del mouse, richiama View.requestPointerCapture().

requestPointerCapture() funziona solo se la gerarchia di visualizzazione contenente i tuoi vista principale. Per questo motivo, non puoi acquisire l'acquisizione del puntatore Chiamata di onCreate. Devi attendere che l'interazione del giocatore completi l'acquisizione il puntatore del mouse, ad esempio quando interagisci con il menu principale, o utilizza onWindowFocusChanged di Google. 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();
    }
}

Eventi acquisiti da requestPointerCapture() vengono inviati alla vista attivabile che 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 acquisizioni del mouse esclusive, ad esempio per consentire ai giocatori di interagire con un menu di pausa, richiama View.releasePointerCapture().