Fare girişi

Bu konuda, giriş çeviri modunun ideal bir oyuncu deneyimi sunmadığı oyunlarda PC Üzerinde Google Play Games için fare girişi nasıl uygulanacağı açıklanmaktadır.

PC oyuncuları genellikle dokunmatik ekran yerine klavye ve fare kullanır. Bu nedenle, oyununuzun fare girişini destekleyip desteklemediğini göz önünde bulundurmanı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. Bu, "giriş çevirisi modu" olarak bilinir.

Bu mod, oyununuzun işlevsel hale gelmesini sağlasa da PC oyuncularına doğal bir deneyim sunmaz. Bu nedenle, aşağıdakileri uygulamanızı öneririz:

  • Basılı tutma işlemleri yerine bağlam 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ıklama
  • Basıp sürükleme etkinliği yerine birinci veya üçüncü şahıs aksiyon oyunları için fareyle bakma

Bilgisayarlarda 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'de giriş işleme, ChromeOS'tekiyle aynıdır. PC'leri destekleyen değişiklikler, oyununuzu tüm Android oyuncuları için de iyileştirir.

Giriş çevirisi modunu devre dışı bırakma

AndroidManifest.xml dosyanızda, android.hardware.type.pc özelliğini beyan edin. Bu, oyununuzun PC donanımını kullandığını ve giriş çevirisi modunu devre dışı bıraktığını gösterir. Ayrıca, required="false" eklemek, oyununuzun fare içermeyen telefon ve tabletlere yüklenmeye devam edebilmesini sağlar. Örneğin:

<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 görev çubuğu simgesini sağ tıklayıp Geliştirici Seçenekleri'ni ve ardından PC modu(KiwiMouse)'u seçerek ham fare girişi almanız gerekir.

İçerik menüsünde seçilen &quot;PC modu(KiwiMouse)&quot;nun ekran görüntüsü

Bunu yaptıktan sonra fare hareketi, View.onGenericMotionEvent tarafından SOURCE_MOUSE kaynağıyla bildirilir. Bu kaynak, fare etkinliği olduğunu gösterir.

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şleme hakkında ayrıntılı bilgi için ChromeOS belgelerine 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, kullanıcının bir oyundaki düğmelerin veya nesnelerin üzerine gelmesini algılamak için en iyi yöntemdir. Böylece, ipucu kutusu gösterebilir veya oyuncunun ne seçeceğini vurgulamak için fareyle üzerine gelme durumu uygulayabilirsiniz. Örneğin:

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

Bilgisayarlarda uzun süredir hem sol hem de sağ fare düğmesi bulunur. Bu sayede etkileşimli öğeler hem birincil hem de ikincil işlemlere izin verir. Oyunlarda, düğmeye dokunma gibi işlemler en iyi şekilde sol tıklamayla eşlenir. Dokunup basılı tutma işlemleri ise sağ tıklamayla daha doğal bir şekilde gerçekleştirilir. Gerçek zamanlı strateji oyunlarında seçmek için sol tıklamayı, taşımak için sağ tıklamayı da kullanabilirsiniz. Birinci şahıs nişancı oyunlarında birincil ve ikincil ateşleme, sol ve sağ tıklamaya atanabilir. Sonsuz koşu oyunlarında zıplamak için sol tıklama, hızlı koşmak için sağ tıklama kullanılabilir. Orta tıklama etkinliği için destek eklemedik.

Düğme basma işlemlerini işlemek için ACTION_DOWN ve ACTION_UP tuşlarını kullanın. Ardından, işlemi hangi düğmenin tetiklediğini belirlemek için getActionButton, tüm düğmelerin durumunu almak için getButtonState kullanın.

Bu örnekte, getActionButton sonucunun gösterilmesine yardımcı olması için bir enum kullanılmaktadı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ırmayı işleme

Oyununuzda yakınlaştırmak için parmakla yakınlaştırma hareketleri veya kaydırma alanlarına dokunup sürükleme yerine farenin kaydırma tekerleğini kullanmanızı öneririz.

Kaydırma tekerleği değerlerini okumak için ACTION_SCROLL etkinliğini dinleyin. Son kareden bu yana delta, dikey dengeleme için AXIS_VSCROLL ve yatay dengeleme için AXIS_HSCROLL ile birlikte getAxisValue kullanılarak alınabilir. Örneğin:

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

Bazı oyunlar, fare hareketini kamera hareketine eşleyen birinci veya üçüncü şahıs aksiyon oyunları gibi, fare imlecinin tam kontrolünü ele geçirmelidir. Fareyi özel olarak kontrol etmek için View.requestPointerCapture() işlevini çağırın.

requestPointerCapture() yalnızca görünümünüzü içeren görünüm hiyerarşisi odaklandığında çalışır. Bu nedenle, onCreate geri çağırmasında işaretçi yakalama elde edemezsiniz. Fare işaretçisini yakalamak için oyuncu etkileşimini (ör. ana menüyle etkileşim) beklemeniz veya onWindowFocusChanged geri çağırma işlevini kullanmanız gerekir. Örneğin:

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 kaydeden odaklanılabilir görünüme gönderilir. Örneğin:

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;
});

Oyuncuların duraklatma menüsüyle etkileşime girmesine izin vermek gibi özel fare yakalama işlevini etkinleştirmek için View.releasePointerCapture() işlevini çağırın.