Fare girişi

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.

Bağlam menüsünde &quot;PC modu(KiwiMouse)&quot;nun seçili olduğu ekran görüntüsü

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.