Kumanda işlemlerini gerçekleştirme

Sistem düzeyinde Android raporları, oyun kumandalarından gelen etkinlik kodlarını girer. şekilde içe aktarabilirsiniz. Oyununuzda bu kodları alabilirsiniz dönüştürebilir ve bunları belirli oyun içi işlemlere dönüştürebilirsiniz.

Oyuncuların bir oyun kumandasına fiziksel olarak bağlanması veya oyun kumandasını kablosuz olarak eşlemesi denetleyiciyi otomatik olarak algılar. olarak ayarlanır ve giriş etkinliklerini raporlamaya başlar. Oyununuz şunları alabilir: aşağıdaki geri çağırma yöntemlerini uygulayarak bu giriş etkinliklerini Activity veya odak noktası View ( Activity veya View (ikisi birden değil):

Önerilen yaklaşım, etkinlikleri Kullanıcının etkileşimde bulunduğu belirli View nesnesi. Bilgi almak için geri çağırma işlevinin sağladığı aşağıdaki nesneleri inceleyin. alınan giriş etkinliğinin türü hakkında:

KeyEvent
Yönlü tanımlamayı açıklayan bir nesne (D-pad) ve oyun kumandası düğmesi etkinlikleri. Önemli etkinliklere bir eşlik eder: Tetiklenen düğmeyi belirten anahtar kodu (örneğin, DPAD_DOWN veya BUTTON_A. Web sitemiz g.co/newsinitiative/labs üzerinden getKeyCode() numaralı telefonu çağırarak veya anahtardan anahtar kodu kullanın etkinlik geri çağırmaları onKeyDown().
MotionEvent
Kontrol çubuğu ve omuz tetikleyiciden gelen girişi tanımlayan bir nesne hareketler. Hareket etkinliklerine bir işlem kodu ve bir dizi eksen değerlerine göre ayarlayın. İşlem kodu, gerçekleşen durum değişikliğini belirtir hareket eden kontrol çubuğu gibi. Eksen değerleri, konumu ve diğer öğeleri belirli bir fiziksel kontrol için hareket özellikleri (ör. AXIS_X veya AXIS_RTRIGGER. İşlem kodunu getAction() ve eksen değerini çağırarak getAxisValue() aranıyor.

Bu ders en yaygın proje yönetimi metodolojilerinden gelen girdileri fiziksel kontroller (oyun kumandası düğmeleri, yön tuşları joystick) ekleyebilirsiniz. View geri çağırma yöntemi ve işleme KeyEvent ve MotionEvent nesneleri.

Oyun kumandasının bağlandığını doğrulama

Android, giriş etkinliklerini raporlarken bunları ayırt etmez oyun kumandası olmayan bir cihazdan gelen etkinlikler ile gelen etkinlikler arasında oyun kumandasından yararlanabilirsiniz. Örneğin, dokunmatik ekran işlemi X'i temsil eden AXIS_X etkinliği koordinatını belirlemeye çalışır, ancak kontrol çubuğu Kontrol çubuğunun X konumunu temsil eden AXIS_X etkinliği. Eğer Oyununuzun oyun kumandası girişlerini yönetmeyle ilgili olduğunu unutmayın. giriş etkinliğinin alakalı bir kaynak türünden geldiğini gösterir.

Bağlı bir giriş cihazının oyun kumandası olduğunu doğrulamak için şunu arayın: getSources() ile Söz konusu cihazda desteklenen giriş kaynağı türleri. Sonra da test edebilirsiniz. şu alanlar ayarlanır:

  • SOURCE_GAMEPAD kaynak türü giriş cihazında oyun kumandası düğmeleri bulunduğunu (örneğin, BUTTON_A) tıklayın. Bu kaynağın oyun kumandasında D-pad düğmeleri olup olmadığını kesin olarak belirtmediğinden, Oyun kumandalarında genelde yön tuşları vardır.
  • SOURCE_DPAD kaynak türü, giriş cihazında D-pad düğmeleri varsa (örneğin, DPAD_UP) tıklayın.
  • SOURCE_JOYSTICK kaynak türü giriş cihazında analog kontrol çubuklarının (örneğin, AXIS_X boyunca hareketleri kaydeden kontrol çubuğu ve AXIS_Y).

Aşağıdaki kod snippet'i, bağlı giriş cihazları da oyun kumandaları. Bu durumda, yöntem oyun kumandalarının cihaz kimlikleri. Daha sonra her cihazı ilişkilendirebilirsiniz Oyununuzdaki bir oyuncuyla kimlik belirleyin ve bağlı her oyuncu için oyun işlemlerini işleyin oynatıcıları ayrı ayrı oynatır. Birden fazla oyun kumandasını destekleme hakkında daha fazla bilgi edinmek için aynı Android cihaza bağlı olan uygulamalar için bkz. Birden fazla oyun kumandasını destekler.

Kotlin

fun getGameControllerIds(): List<Int> {
    val gameControllerDeviceIds = mutableListOf<Int>()
    val deviceIds = InputDevice.getDeviceIds()
    deviceIds.forEach { deviceId ->
        InputDevice.getDevice(deviceId).apply {

            // Verify that the device has gamepad buttons, control sticks, or both.
            if (sources and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD
                    || sources and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK) {
                // This device is a game controller. Store its device ID.
                gameControllerDeviceIds
                        .takeIf { !it.contains(deviceId) }
                        ?.add(deviceId)
            }
        }
    }
    return gameControllerDeviceIds
}

Java

public ArrayList<Integer> getGameControllerIds() {
    ArrayList<Integer> gameControllerDeviceIds = new ArrayList<Integer>();
    int[] deviceIds = InputDevice.getDeviceIds();
    for (int deviceId : deviceIds) {
        InputDevice dev = InputDevice.getDevice(deviceId);
        int sources = dev.getSources();

        // Verify that the device has gamepad buttons, control sticks, or both.
        if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
                || ((sources & InputDevice.SOURCE_JOYSTICK)
                == InputDevice.SOURCE_JOYSTICK)) {
            // This device is a game controller. Store its device ID.
            if (!gameControllerDeviceIds.contains(deviceId)) {
                gameControllerDeviceIds.add(deviceId);
            }
        }
    }
    return gameControllerDeviceIds;
}

Ayrıca, bağımsız giriş özelliklerini kontrol etmek isteyebilirsiniz. tarafından desteklenir. Bu, örneğin Oyununuzun yalnızca, içerdiği fiziksel kontroller grubundan gelen girişleri kullanmasını istiyorsunuz. anlar.

Belirli bir tuş kodunun veya eksen kodunun bağlı bir kuruluş tarafından desteklenip desteklenmediğini tespit etmek için oyun kumandası için aşağıdaki teknikleri kullanın:

  • Android 4.4 (API düzeyi 19) veya sonraki sürümlerde bir anahtar kodunun şu numarayı çağırarak bağlı bir oyun kumandasında desteklenir: hasKeys(int...)
  • Android 3.1 (API düzeyi 12) veya sonraki sürümlerde kullanılabilen tüm eksenleri bulabilirsiniz ilk olarak çağırarak bağlı bir oyun kumandasında desteklenir getMotionRanges() Ardından, her bir InputDevice.MotionRange nesne döndürüldü, çağrı Eksen kimliğini almak için getAxis() tuşlarına basın.

Oyun kumandası düğmesine basılan düğmeleri işle

Şekil 1'de, Android'in anahtar kodları ve eksen değerlerini fiziksel Çoğu oyun kumandasında geçerli olan bir kontroldür.

Şekil 1. Genel bir oyun kumandası profili.

Şekildeki açıklama metinleri aşağıdakilere karşılık gelir:

Oyun kumandası düğmesine basıldığında oluşturulan yaygın tuş kodları arasında şunlar yer alır: BUTTON_A, BUTTON_B, BUTTON_SELECT, ve BUTTON_START. Bir oyun kumandalar, D-pad çapraz çubuğuna orta basıldığında da DPAD_CENTER tuş kodunu tetikler. Sizin oyun, getKeyCode() öğesini çağırarak anahtar kodu inceleyebilir gibi önemli etkinlik çağrılarından onKeyDown(), Oyununuzla ilgili bir etkinliği temsil ediyorsa bunu bir çok iyi bir oyundur. Tablo 1'de, en yaygın kullanılanlar için önerilen oyun işlemleri oyun kumandası düğmeleri.

Tablo 1. Oyun kumandası için önerilen oyun işlemleri düğmelerini kullanın.

Aksiyon Düğme Tuşu Kodu
Oyunu ana menüden başlatın veya oyun sırasında duraklatın/duraklatmayı kaldırın BUTTON_START*
Menüyü göster BUTTON_SELECT* ve KEYCODE_MENU*
Android Geri gezinme davranışıyla aynıdır. Gezinme tasarımı rehberini inceleyin. KEYCODE_BACK
Menüdeki önceki bir öğeye geri gitme BUTTON_B
Seçimi onaylayın veya birincil oyun işlemini gerçekleştirin BUTTON_A ve DPAD_CENTER

* Oyununuzda Başlat, Seç veya Menü seçenekleri bulunmamalıdır. düğmelerini kullanın.

İpucu: Yapılandırma ekranı sağlayabilirsiniz kullanıcıların kendi oyun kumandası eşlemelerini oyun işlemleri için de geçerlidir.

Aşağıdaki snippet, onKeyDown() - BUTTON_A ve DPAD_CENTER düğmesine basıldığında bunu basit bir oyunda bulabilirsiniz.

Kotlin

class GameView(...) : View(...) {
    ...

    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        var handled = false
        if (event.source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD) {
            if (event.repeatCount == 0) {
                when (keyCode) {
                    // Handle gamepad and D-pad button presses to navigate the ship
                    ...

                    else -> {
                        keyCode.takeIf { isFireKey(it) }?.run {
                            // Update the ship object to fire lasers
                            ...
                            handled = true
                        }
                    }
                }
            }
            if (handled) {
                return true
            }
        }
        return super.onKeyDown(keyCode, event)
    }

    // Here we treat Button_A and DPAD_CENTER as the primary action
    // keys for the game.
    private fun isFireKey(keyCode: Int): Boolean =
            keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_BUTTON_A
}

Java

public class GameView extends View {
    ...

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        boolean handled = false;
        if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)
                == InputDevice.SOURCE_GAMEPAD) {
            if (event.getRepeatCount() == 0) {
                switch (keyCode) {
                    // Handle gamepad and D-pad button presses to
                    // navigate the ship
                    ...

                    default:
                         if (isFireKey(keyCode)) {
                             // Update the ship object to fire lasers
                             ...
                             handled = true;
                         }
                     break;
                }
            }
            if (handled) {
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    private static boolean isFireKey(int keyCode) {
        // Here we treat Button_A and DPAD_CENTER as the primary action
        // keys for the game.
        return keyCode == KeyEvent.KEYCODE_DPAD_CENTER
                || keyCode == KeyEvent.KEYCODE_BUTTON_A;
    }
}

Not: Android 4.2 (API) sürümünde 17. seviye) ve altındaki kullanıcılar için BUTTON_A, Android Geri tuşu varsayılan olarak kullanılır. Uygulamanız bu Android cihazları destekliyorsa emin olun: Birincil maç olarak BUTTON_A eyleme dökülebilir. Mevcut Android SDK'sını belirlemek için sürümünü öğrenmek için Build.VERSION.SDK_INT değer.

Yön tuşlarıyla giriş yap

4 yönlü yön tuşları (D-pad) çoğu oyunda yaygın olarak kullanılan bir fiziksel kontroldür kontrol eder. Android, D-pad'e YUKARI ve AŞAĞI tuşlarına bastığını bildirir. Aralıkta AXIS_HAT_Y etkinlik -1,0 (yukarı) ile 1,0 (aşağı) arasındadır ve D-pad SOL veya SAĞ tuşuna basar. -1,0 aralığında AXIS_HAT_X etkinlik (solda) - 1,0 (sağ).

Bunun yerine bazı kumandalar d-pad'e basmaları bir tuş koduyla bildirir. Oyununuz ve D-pad'e basma işlemleriyle ilgileniyorsa, şapka ekseni etkinliklerini ve D-pad'i tuş kodlarını aynı giriş etkinlikleriyle aynı olarak ayarlayın.

Tablo 2. D-pad tuşu için önerilen varsayılan oyun işlemleri değerleri ve şapka ekseni değerlerini belirlemenize yardımcı olur.

Aksiyon D-pad Anahtar Kodu Şapka Eksen Kodu
Yukarı Taşı KEYCODE_DPAD_UP AXIS_HAT_Y (0 ile -1,0 arasındaki değerler için)
Aşağı Taşı KEYCODE_DPAD_DOWN AXIS_HAT_Y (0 - 1,0 değerleri için)
Sola Taşı KEYCODE_DPAD_LEFT AXIS_HAT_X (0 ile -1,0 arasındaki değerler için)
Sağa Taşı KEYCODE_DPAD_RIGHT AXIS_HAT_X (0 - 1,0 değerleri için)

Aşağıdaki kod snippet'i, şapkayı kontrol etmenize olanak tanıyan bir yardımcı sınıfı eksen ve anahtar kod değerlerini kullanır.

Kotlin

class Dpad {

    private var directionPressed = -1 // initialized to -1

    fun getDirectionPressed(event: InputEvent): Int {
        if (!isDpadDevice(event)) {
            return -1
        }

        // If the input event is a MotionEvent, check its hat axis values.
        (event as? MotionEvent)?.apply {

            // Use the hat axis value to find the D-pad direction
            val xaxis: Float = event.getAxisValue(MotionEvent.AXIS_HAT_X)
            val yaxis: Float = event.getAxisValue(MotionEvent.AXIS_HAT_Y)

            directionPressed = when {
                // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad
                // LEFT and RIGHT direction accordingly.
                xaxis.compareTo(-1.0f) == 0 -> Dpad.LEFT
                xaxis.compareTo(1.0f) == 0 -> Dpad.RIGHT
                // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad
                // UP and DOWN direction accordingly.
                yaxis.compareTo(-1.0f) == 0 -> Dpad.UP
                yaxis.compareTo(1.0f) == 0 -> Dpad.DOWN
                else -> directionPressed
            }
        }
        // If the input event is a KeyEvent, check its key code.
        (event as? KeyEvent)?.apply {

            // Use the key code to find the D-pad direction.
            directionPressed = when(event.keyCode) {
                KeyEvent.KEYCODE_DPAD_LEFT -> Dpad.LEFT
                KeyEvent.KEYCODE_DPAD_RIGHT -> Dpad.RIGHT
                KeyEvent.KEYCODE_DPAD_UP -> Dpad.UP
                KeyEvent.KEYCODE_DPAD_DOWN -> Dpad.DOWN
                KeyEvent.KEYCODE_DPAD_CENTER ->  Dpad.CENTER
                else -> directionPressed
            }
        }
        return directionPressed
    }

    companion object {
        internal const val UP = 0
        internal const val LEFT = 1
        internal const val RIGHT = 2
        internal const val DOWN = 3
        internal const val CENTER = 4

        fun isDpadDevice(event: InputEvent): Boolean =
            // Check that input comes from a device with directional pads.
            event.source and InputDevice.SOURCE_DPAD != InputDevice.SOURCE_DPAD
    }
}

Java

public class Dpad {
    final static int UP       = 0;
    final static int LEFT     = 1;
    final static int RIGHT    = 2;
    final static int DOWN     = 3;
    final static int CENTER   = 4;

    int directionPressed = -1; // initialized to -1

    public int getDirectionPressed(InputEvent event) {
        if (!isDpadDevice(event)) {
           return -1;
        }

        // If the input event is a MotionEvent, check its hat axis values.
        if (event instanceof MotionEvent) {

            // Use the hat axis value to find the D-pad direction
            MotionEvent motionEvent = (MotionEvent) event;
            float xaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_X);
            float yaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_Y);

            // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad
            // LEFT and RIGHT direction accordingly.
            if (Float.compare(xaxis, -1.0f) == 0) {
                directionPressed =  Dpad.LEFT;
            } else if (Float.compare(xaxis, 1.0f) == 0) {
                directionPressed =  Dpad.RIGHT;
            }
            // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad
            // UP and DOWN direction accordingly.
            else if (Float.compare(yaxis, -1.0f) == 0) {
                directionPressed =  Dpad.UP;
            } else if (Float.compare(yaxis, 1.0f) == 0) {
                directionPressed =  Dpad.DOWN;
            }
        }

        // If the input event is a KeyEvent, check its key code.
        else if (event instanceof KeyEvent) {

           // Use the key code to find the D-pad direction.
            KeyEvent keyEvent = (KeyEvent) event;
            if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) {
                directionPressed = Dpad.LEFT;
            } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT) {
                directionPressed = Dpad.RIGHT;
            } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) {
                directionPressed = Dpad.UP;
            } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {
                directionPressed = Dpad.DOWN;
            } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER) {
                directionPressed = Dpad.CENTER;
            }
        }
        return directionPressed;
    }

    public static boolean isDpadDevice(InputEvent event) {
        // Check that input comes from a device with directional pads.
        if ((event.getSource() & InputDevice.SOURCE_DPAD)
             != InputDevice.SOURCE_DPAD) {
             return true;
         } else {
             return false;
         }
     }
}

Bu yardımcı sınıfı, oyununuzda işlemek istediğiniz her yerde kullanabilirsiniz D-pad girişi (örneğin, onGenericMotionEvent() veya onKeyDown() (geri çağırmalar).

Örnek:

Kotlin

private val dpad = Dpad()
...
override fun onGenericMotionEvent(event: MotionEvent): Boolean {
    if (Dpad.isDpadDevice(event)) {
        when (dpad.getDirectionPressed(event)) {
            Dpad.LEFT -> {
                // Do something for LEFT direction press
                ...
                return true
            }
            Dpad.RIGHT -> {
                // Do something for RIGHT direction press
                ...
                return true
            }
            Dpad.UP -> {
                // Do something for UP direction press
                ...
                return true
            }
            ...
        }
    }

    // Check if this event is from a joystick movement and process accordingly.
    ...
}

Java

Dpad dpad = new Dpad();
...
@Override
public boolean onGenericMotionEvent(MotionEvent event) {

    // Check if this event if from a D-pad and process accordingly.
    if (Dpad.isDpadDevice(event)) {

       int press = dpad.getDirectionPressed(event);
       switch (press) {
            case LEFT:
                // Do something for LEFT direction press
                ...
                return true;
            case RIGHT:
                // Do something for RIGHT direction press
                ...
                return true;
            case UP:
                // Do something for UP direction press
                ...
                return true;
            ...
        }
    }

    // Check if this event is from a joystick movement and process accordingly.
    ...
}

Kontrol çubuğu hareketlerini işleme

Oyuncular oyun kumandalarında kontrol çubuğunu hareket ettirdiğinde Android, Şunları içeren MotionEvent: ACTION_MOVE işlem kodu ve güncellenen eksenlerinin konumunu belirler. Oyununuz, kontrol çubuğunun hareket edip etmediğini belirlemek için MotionEvent önemsediğini bilir.

Kontrol çubuğu hareket etkinliklerinin, birden çok hareket örneğini birlikte toplu olarak alabileceğini unutmayın tek bir nesne içinde. MotionEvent nesnesi şunu içerir: her kontrol çubuğu ekseni için geçerli konumun yanı sıra birden fazla geçmiş için belirlemek de önemlidir. Android, ACTION_MOVE işlem koduyla hareket etkinliklerini (kontrol çubuğu hareketleri gibi) bildirirken, eksen değerlerine bakarak anlayabilirsiniz. Bir eksene ait geçmiş değerler şunlardan oluşur: mevcut eksen değerinden daha eski ve şundan daha yeni olan farklı değer kümesi önceki hareket etkinliklerinde raporlanan değerler. Bkz. Ayrıntılar için MotionEvent referansına gidin.

Bir oyunu daha doğru şekilde oluşturmak için geçmiş bilgilerini kullanabilirsiniz kontrol çubuğu girişine bağlı olarak nesnenin hareketini ayarlayabilirsiniz. Alıcı: mevcut ve geçmiş değerleri almak için getAxisValue() veya getHistoricalAxisValue(). Ayrıca, geçmişteki aktivitelerin sayısını da toplayarak kontrol çubuğu etkinliğindeki puanları getHistorySize()

Aşağıdaki snippet, Kontrol çubuğu girişini işlemek için onGenericMotionEvent() geri çağırma. Öncelikle bir eksenin geçmiş değerlerini işleyip ardından mevcut konumunu işleyin.

Kotlin

class GameView(...) : View(...) {

    override fun onGenericMotionEvent(event: MotionEvent): Boolean {

        // Check that the event came from a game controller
        return if (event.source and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK
                && event.action == MotionEvent.ACTION_MOVE) {

            // Process the movements starting from the
            // earliest historical position in the batch
            (0 until event.historySize).forEach { i ->
                // Process the event at historical position i
                processJoystickInput(event, i)
            }

            // Process the current movement sample in the batch (position -1)
            processJoystickInput(event, -1)
            true
        } else {
            super.onGenericMotionEvent(event)
        }
    }
}

Java

public class GameView extends View {

    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {

        // Check that the event came from a game controller
        if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) ==
                InputDevice.SOURCE_JOYSTICK &&
                event.getAction() == MotionEvent.ACTION_MOVE) {

            // Process all historical movement samples in the batch
            final int historySize = event.getHistorySize();

            // Process the movements starting from the
            // earliest historical position in the batch
            for (int i = 0; i < historySize; i++) {
                // Process the event at historical position i
                processJoystickInput(event, i);
            }

            // Process the current movement sample in the batch (position -1)
            processJoystickInput(event, -1);
            return true;
        }
        return super.onGenericMotionEvent(event);
    }
}

Kontrol çubuğu girişini kullanmadan önce, kontrol çubuğunun ardından eksen hareketlerini buna göre hesaplayın. Kontrol çubukları genellikle düz bir alana, yani (0,0) koordinatına yakın bir değer aralığına sahiptir eksenin ortalanmış kabul edildiği başlangıç noktasıdır. Eksen değeri Android düz bir alanda kaldığı için kumandayı hareketsiz (yani her iki eksende hareketsiz) oluşur.

Aşağıdaki snippet, hareket boyunca hareketi hesaplayan yardımcı bir yöntemi göstermektedir görebilirsiniz. Bu yardımcıyı processJoystickInput() yönteminde çağırırsınız aşağıda ayrıntılı olarak açıklanmıştır.

Kotlin

private fun getCenteredAxis(
        event: MotionEvent,
        device: InputDevice,
        axis: Int,
        historyPos: Int
): Float {
    val range: InputDevice.MotionRange? = device.getMotionRange(axis, event.source)

    // A joystick at rest does not always report an absolute position of
    // (0,0). Use the getFlat() method to determine the range of values
    // bounding the joystick axis center.
    range?.apply {
        val value: Float = if (historyPos < 0) {
            event.getAxisValue(axis)
        } else {
            event.getHistoricalAxisValue(axis, historyPos)
        }

        // Ignore axis values that are within the 'flat' region of the
        // joystick axis center.
        if (Math.abs(value) > flat) {
            return value
        }
    }
    return 0f
}

Java

private static float getCenteredAxis(MotionEvent event,
        InputDevice device, int axis, int historyPos) {
    final InputDevice.MotionRange range =
            device.getMotionRange(axis, event.getSource());

    // A joystick at rest does not always report an absolute position of
    // (0,0). Use the getFlat() method to determine the range of values
    // bounding the joystick axis center.
    if (range != null) {
        final float flat = range.getFlat();
        final float value =
                historyPos < 0 ? event.getAxisValue(axis):
                event.getHistoricalAxisValue(axis, historyPos);

        // Ignore axis values that are within the 'flat' region of the
        // joystick axis center.
        if (Math.abs(value) > flat) {
            return value;
        }
    }
    return 0;
}

Her şeyi bir araya getirerek kontrol çubuğu hareketlerini oyununuz:

Kotlin

private fun processJoystickInput(event: MotionEvent, historyPos: Int) {

    val inputDevice = event.device

    // Calculate the horizontal distance to move by
    // using the input value from one of these physical controls:
    // the left control stick, hat axis, or the right control stick.
    var x: Float = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos)
    if (x == 0f) {
        x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos)
    }
    if (x == 0f) {
        x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos)
    }

    // Calculate the vertical distance to move by
    // using the input value from one of these physical controls:
    // the left control stick, hat switch, or the right control stick.
    var y: Float = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos)
    if (y == 0f) {
        y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos)
    }
    if (y == 0f) {
        y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos)
    }

    // Update the ship object based on the new x and y values
}

Java

private void processJoystickInput(MotionEvent event,
        int historyPos) {

    InputDevice inputDevice = event.getDevice();

    // Calculate the horizontal distance to move by
    // using the input value from one of these physical controls:
    // the left control stick, hat axis, or the right control stick.
    float x = getCenteredAxis(event, inputDevice,
            MotionEvent.AXIS_X, historyPos);
    if (x == 0) {
        x = getCenteredAxis(event, inputDevice,
                MotionEvent.AXIS_HAT_X, historyPos);
    }
    if (x == 0) {
        x = getCenteredAxis(event, inputDevice,
                MotionEvent.AXIS_Z, historyPos);
    }

    // Calculate the vertical distance to move by
    // using the input value from one of these physical controls:
    // the left control stick, hat switch, or the right control stick.
    float y = getCenteredAxis(event, inputDevice,
            MotionEvent.AXIS_Y, historyPos);
    if (y == 0) {
        y = getCenteredAxis(event, inputDevice,
                MotionEvent.AXIS_HAT_Y, historyPos);
    }
    if (y == 0) {
        y = getCenteredAxis(event, inputDevice,
                MotionEvent.AXIS_RZ, historyPos);
    }

    // Update the ship object based on the new x and y values
}

Daha gelişmiş oyun kumandalarını desteklemek için özellikleri kullanmak için aşağıdaki en iyi uygulamaları izleyin:

  • Çift kumanda çubuğunu tutma. Birçok oyun kumandasında hem sol hem sağ kontrol çubuğu. Soldaki çubuk için Android yatay hareketleri AXIS_X etkinlik olarak raporlar ve dikey hareketler AXIS_Y etkinlik olarak gösterilir. Android, sağ çubuk için yatay hareketleri AXIS_Z etkinlik ve dikey hareket: AXIS_RZ etkinlik. Tüm URL'lerinizi her iki kumanda da kodunuza gömülür.
  • Kenar tetiği basışlarını tutma (ancak alternatif giriş sağlama) ). Bazı kumandaların sol ve sağ omzu bulunur tetikleyiciler için geçerlidir. Bu tetikleyiciler mevcutsa Android, sol tetikleyiciye basıldığını bildirir AXIS_LTRIGGER etkinliği ve olarak sağ tetikleyici basın AXIS_RTRIGGER etkinliği. Android'de 4.3 (API düzeyi 18) test eden bir denetleyici, AXIS_LTRIGGER adlı kullanıcı ayrıca AXIS_BRAKE ekseni için aynı değere sahiptir. İlgili içeriği oluşturmak için kullanılan aynısı AXIS_RTRIGGER ve AXIS_GAS. Android, tüm analog tetikleyicileri bildiriyor 0,0 (bölünmüş) ile 1,0 (tamamen basılmış) arasında normalleştirilmiş bir değerle basar. Değil tüm kumandaların tetikleyicileri vardır, bu nedenle oyuncuların bunları yapmasına izin verebilirsiniz oyun eylemlerini temsil eder.