Bu konu, giriş çeviri modunun ideal bir oyuncu deneyimi sunmadığı oyunlarda PC'de Google Play Games için fare girişinin nasıl uygulanacağını kapsar.
PC oyuncuları genellikle dokunmatik ekran yerine klavye ve fare kullanır. Bu nedenle, oyununuzun fare girişini destekleyip desteklemediğini dikkate almanız önemlidir. PC Üzerinde Google Play Games, varsayılan olarak tüm sol tıklama fare etkinliklerini tek bir sanal dokunma etkinliğine dönüştürür. Buna "giriş çevirisi modu" denir.
Bu mod, oyununuzu birkaç değişiklikle çalışır hale getirse de PC oyuncularına yerel bir deneyim sunmaz. Bunun için aşağıdakileri uygulamanızı öneririz:
- Basılı tutma işlemleri yerine içerik menüleri için fareyle üzerine gelme durumları
- Uzun basma veya içerik menüsünde gerçekleşen alternatif işlemler için sağ tıklayın
- Birinci veya üçüncü şahıs aksiyon oyunlarında basma ve sürükleme etkinliği yerine fareyle bakma
PC'lerde yaygın olan kullanıcı arayüzü kalıplarını desteklemek için giriş çevirisi modunu devre dışı bırakmanız gerekir.
PC Üzerinde Google Play Games'in giriş işlemleri, ChromeOS ile aynıdır. PC'leri destekleyen değişiklikler, oyununuzu tüm Android oyuncuları için de iyileştiriyor.
Giriş çevirisi modunu devre dışı bırakma
AndroidManifest.xml
dosyanızda android.hardware.type.pc
özelliğini tanımlayın.
Bu, oyununuzun PC donanımı kullandığını ve giriş çevirisi modunu devre dışı bıraktığını gösterir. Ayrıca, required="false"
eklemek, oyununuzun telefon ve tabletlere fare olmadan da yüklenebilmesini sağlar. Örnek:
<manifest ...>
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
...
</manifest>
PC Üzerinde Google Play Games'in üretim sürümü, bir oyun başlatıldığında doğru moda geçer. Geliştirici emülatöründe çalışırken ham fare girişi almak için görev çubuğu simgesini sağ tıklayıp Geliştirici Seçenekleri'ni, ardından PC modu(KiwiMouse)'nu seçmeniz gerekir.
Bunu yaptıktan sonra fare hareketi, View.onGenericMotionEvent tarafından fare etkinliği olduğunu belirten SOURCE_MOUSE
kaynağıyla bildirilir.
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; });
Fare girişini işlemeyle ilgili ayrıntılar için ChromeOS dokümanlarına bakın.
Fare hareketini işleme
Fare hareketini algılamak için ACTION_HOVER_ENTER
, ACTION_HOVER_EXIT
ve ACTION_HOVER_MOVE
etkinliklerini dinleyin.
Bu en iyi kullanım, kullanıcıyı bir oyunda düğmelerin veya nesnelerin üzerine getirdiğini tespit ederek size bir ipucu kutusu görüntüleme veya oyuncunun neyi seçmek üzere olduğunu vurgulamak için bir ipucu kutusu gösterme fırsatı verir. Örnek:
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; });
Fare düğmelerini kullanma
Etkileşimli öğelere hem birincil hem de ikincil işlemler sağlayan PC'lerde uzun zamandır hem sol hem sağ fare düğmeleri kullanılıyor. Bir oyunda, düğmeye dokunma gibi dokunma işlemleri en iyi şekilde sol tıklamayla eşlenir. Dokun ve tut işlemleri ise sağ tıklamayla en doğal şekilde hissedilir. Gerçek zamanlı strateji oyunlarında, seçmek için sol tıklama ve taşımak için sağ tıklama seçeneklerini de kullanabilirsiniz. Birinci şahıs nişancı oyunlarında birincil ve ikincil ateşleme, sol ve sağ tıklamaya atanabilir. Sonsuz koşucu oyunlarında, atlamak için sol tıklama, hızlanmak için sağ tıklama kullanılabilir. Orta tıklama etkinliği için destek eklenmemiştir.
Düğme basma işlemlerini ACTION_DOWN
ve ACTION_UP
ile yönetin. Ardından, işlemi hangi düğmenin tetiklediğini belirlemek için getActionButton
'ü veya tüm düğmelerin durumunu almak için getButtonState
'ü kullanın.
Bu örnekte, getActionButton
sonucunun görüntülenmesine yardımcı olması için bir numaralandırma kullanılmıştır:
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; } } }
Bu örnekte, işlem fareyle üzerine gelme etkinliklerine benzer şekilde ele alınır:
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; });
Fare tekerleğiyle kaydırma işlemini yönetme
Yakınlaştırmak için iki parmağınızı yakınlaştırmak yerine fare kaydırma tekerleğini kullanmanızı veya oyununuzda kaydırma alanlarını dokunup sürüklemenizi öneririz.
Kaydırma tekerleği değerlerini okumak için ACTION_SCROLL
etkinliğini dinleyin. Son karekten itibaren delta, dikey kaydırma için AXIS_VSCROLL
ve yatay kaydırma için AXIS_HSCROLL
ile getAxisValue
kullanılarak alınabilir. Örnek:
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; });
Fare girişini yakalama
Fare hareketini kamera hareketiyle eşleyen birinci veya üçüncü şahıs aksiyon oyunları gibi bazı oyunların fare imlecini tamamen kontrol etmesi gerekir. Farenin münhasır kontrolünü ele almak için View.requestPointerCapture()
simgesini çağırın.
requestPointerCapture()
yalnızca görünümünüzü içeren görünüm hiyerarşisi odaktayken çalışır. Bu nedenle, onCreate
geri çağırma işlevinde işaretçi yakalama işlemini gerçekleştiremezsiniz. Örneğin, ana menüyle etkileşimde bulunurken fare işaretçisini yakalamak için oynatıcı etkileşiminin tamamlanmasını beklemeli veya onWindowFocusChanged
geri çağırma özelliğini kullanmalısınız. Örnek:
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(); } }
requestPointerCapture()
tarafından yakalanan etkinlikler, OnCapturedPointerListener
değerini kaydeden odaklanılabilir görünüme gönderilir. Örnek:
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; });
Oyunculara duraklatma menüsüyle etkileşim kurmalarına izin vermek gibi özel fare yakalama işlemlerini başlatmak için View.releasePointerCapture()
öğesini çağırın.