Fare girişi

Bu konuda, giriş çevirisi modunun ideal bir oyuncu deneyimi sunmadığı oyunlar için PC Üzerinde Google Play Games'de fare girişinin nasıl uygulanacağı ele alınmaktadır.

PC oyuncularında genellikle dokunmatik ekran yerine klavye ve fare bulunur. Bu nedenle, oyununuzun fare girdisine uygun olup olmadığını değerlendirmeniz ö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ş çeviri modu" olarak bilinir.

Bu mod birkaç değişiklikle oyununuzu çalışır hale getirse de PC oyuncularına yerel hissi veren bir deneyim sunmaz. Bunun için aşağıdakileri uygulamanızı öneririz:

  • Açma ve basılı tutma işlemleri yerine içerik menüleri için fareyle üzerine gelme durumları
  • Uzun basıldığında veya bir içerik menüsünde gerçekleşen alternatif işlemler için sağ tıklayın.
  • Basın ve sürükleme etkinliği yerine birinci veya üçüncü şahıs aksiyon oyunları için fareyle üzerine gelme

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 giriş işleme şekli, ChromeOS ile aynıdır. PC'leri destekleyen değişiklikler aynı zamanda oyununuzu tüm Android oyuncuları için daha iyi hale getirir.

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

AndroidManifest.xml dosyanızda android.hardware.type.pc özelliğini beyan edin. 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 yüklenebilmesini 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 kullanıma sunulduğunda doğru moda geçer. Geliştirici emülatöründe çalışırken ham fare girişini almak için görev çubuğu simgesini sağ tıklayıp Geliştirici Seçenekleri'ni ve ardından PC modunu(KiwiMouse) seçmeniz gerekir.

İçerik menüsünde seçili &quot;PC mode(KiwiMouse)&quot; seçeneğinin ekran görüntüsü

Bunu yapmanızdan sonra, fare hareketi View.onGeneralMotionEvent tarafından, kaynak SOURCE_MOUSE ile raporlanarak bunun bir fare etkinliği olduğunu belirtir.

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 hareketlerini işleme

Fare hareketlerini algılamak için ACTION_HOVER_ENTER, ACTION_HOVER_EXIT ve ACTION_HOVER_MOVE etkinliklerini dinleyin.

Bu, bir oyunda kullanıcıyı düğmelerin veya nesnelerin üzerine getirdiğini algılamak için en iyi seçenektir. Size, bir ipucu kutusu görüntüleme veya bir oyuncunun seçmek üzere olduğu öğeyi vurgulamak için fareyle üzerine gelme durumu uygulama şansı verir. Ö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

PC'lerde uzun zamandır hem sol hem sağ fare düğmeleri olduğu için, birincil ve ikincil işlemlere etkileşimli öğeler ekledik. Bir oyunda, bir düğmeye dokunma gibi dokunma eylemlerinin en uygun olduğu yer, dokunma ve basılı tutma işlemlerinin sağ tıklamayla en doğal olduğu durum. Gerçek zamanlı strateji oyunlarında seçim yapmak için sol tıklama ve hareket etmek için sağ tıklama da kullanılabilir. Birinci şahıs nişancı oyunlarında sol tarafa birincil ve ikincil ateşleme ve sağ tıklama atanır. Sonsuz koşucu, zıplamak için sol tıklamayı, koşmak için sağ tıklamayı kullanabilir. Orta tıklama etkinliği için destek eklemedik.

Düğmelere basmaları işlemek için ACTION_DOWN ve ACTION_UP kullanın. Ardından, işlemi hangi düğmenin tetiklediğini belirlemek için getActionButton veya tüm düğmelerin durumunu almak için getButtonState işlevini kullanın.

Bu örnekte, getActionButton sonucunun gösterilmesine yardımcı olmak için bir enum 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 işlenir:

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ği kaydırmasını kullanın

Hareketleri yakınlaştırmak veya oyununuzdaki kaydırma alanlarına dokunup sürüklemek için sıkıştırmak yerine fare 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 olan delta, dikey ofset için AXIS_VSCROLL ve yatay ofset için AXIS_HSCROLL ile 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 yakala

Fare hareketini kamera hareketleriyle eşleştiren birinci veya üçüncü şahıs aksiyon oyunları gibi bazı oyunların fare imlecinin tam kontrolünü gerçekleştirmesi gerekir. Farenin tamamen kontrolünü almak için View.requestPointerCapture() çağırın.

requestPointerCapture(), yalnızca görünümünüzü içeren görünüm hiyerarşisine odaklanıldığında çalışır. Bu nedenle, onCreate geri çağırmasında işaretçi yakalaması alamazsınız. Ana menüyle etkileşimde bulunurken oyuncu etkileşiminin fare işaretçisini yakalamasını beklemeniz veya onWindowFocusChanged geri çağırmasını 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 alanını 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 bir duraklatma menüsüyle etkileşim kurmasına izin vermek gibi özel fare yakalama özelliğini etkinleştirmek için View.releasePointerCapture() yöntemini çağırın.