コントローラの操作を処理する

システムレベルで、Android はゲーム コントローラからの入力イベントコードを報告します。 キーコードと軸の値です。ゲームでは、これらのコードを 特定のゲーム内アクションに変換できます。

プレーヤーがゲーム コントローラを物理的に接続またはワイヤレスでペア設定すると、 設定すると、コントローラが自動で検出し、 入力デバイスとして指定され、その入力イベントのレポートが開始されます。ゲームでは、 これらの入力イベントを生成するには、 Activity またはフォーカスされた View( のコールバックを実装することで、Activity または View で、両方は不可):

推奨される方法は、API 呼び出しからイベントをキャプチャし、 ユーザーが操作する特定の View オブジェクト。 コールバックによって提供される次のオブジェクトを調べて、情報を取得する :

KeyEvent
方向を表すオブジェクト パッド(D-pad)とゲームパッド ボタンのイベント。キーイベントと同時に トリガーされた特定のボタンを示すキーコード DPAD_DOWN または BUTTON_A。こちらの getKeyCode() を呼び出すか、キーから イベント コールバックを onKeyDown()
MotionEvent
ジョイスティックとショルダー トリガーからの入力を記述するオブジェクト 動きます。モーション イベントには、アクション コードと一連の 軸の値。アクション コードは、発生した状態変化を たとえばジョイスティックの操作などです軸の値では、位置などの関係を 物理制御用の移動プロパティとして、 AXIS_X または AXIS_RTRIGGER。アクションコードは getAction() を呼び出して、その軸の値を getAxisValue() を呼び出しています。

このレッスンでは、最も一般的な種類の入力を処理する方法に焦点を当て、 物理的なコントロール(ゲームパッド ボタン、十字キー、 ジョイスティックなど)をゲーム画面内に設置することで、 View コールバック メソッドと処理 KeyEvent オブジェクトと MotionEvent オブジェクト。

ゲーム コントローラが接続されていることを確認する

入力イベントを報告する際、Android は 発生したイベントと、ゲーム コントローラ以外のデバイスからの ゲーム コントローラから操作できます。たとえば、タッチ スクリーンの操作を行うと、 X を表す AXIS_X イベント 座標ですが、ジョイスティックの場合、 ジョイスティックの X 位置を表す AXIS_X イベント。条件 ゲーム コントローラ入力の処理が重要になります。まず、 入力イベントが関連するソースタイプに由来することを検証できます。

接続されている入力デバイスがゲーム コントローラであることを確認するには、次のコマンドを呼び出します。 getSources(): 結合されたビットフィールドを取得する そのデバイスでサポートされている入力ソースのタイプを指定します。その後、 次のフィールドが設定されます。

  • ソースタイプが SOURCE_GAMEPAD の場合、 入力デバイスにゲームパッド ボタン( BUTTON_A)。このソースは タイプは、ゲーム コントローラに D-pad ボタンがあるかどうかを厳密には示していません。 ただし、ほとんどのゲームパッドには方向コントロールがあります。
  • ソースタイプが SOURCE_DPAD の場合、 入力デバイスに D-pad ボタン( DPAD_UP)。
  • SOURCE_JOYSTICK のソースタイプ 入力デバイスにアナログ制御スティック( AXIS_X での動きを記録するジョイスティック および AXIS_Y)。

次のコード スニペットは、Google Cloud Storage バケットの 接続されている入力デバイスはゲーム コントローラです。存在する場合、メソッドは ゲーム コントローラのデバイス ID です。その後、各デバイスを ID と、接続されている各プレーヤーのゲーム アクションを処理する 表示されます。複数のゲーム コントローラのサポートについて詳しくは、 同じ Android デバイスで同時に接続している場合は、以下をご覧ください。 複数のゲーム コントローラをサポートする

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

また、個々の入力機能を確認し、 ゲーム コントローラでサポートされます。これは、次のような場合に役立ちます。 ゲームで物理コントロール セットからの入力のみを使用する 理解することです

特定のキーコードまたは軸コードが、 以下の手法を使用します。

  • Android 4.4(API レベル 19)以降では、キーコードが 呼び出すことで、接続されているゲーム コントローラで hasKeys(int...)
  • Android 3.1(API レベル 12)以降では、使用可能なすべての軸 ゲーム コントローラでサポートされるようにするには、 getMotionRanges()。その後、 InputDevice.MotionRange オブジェクトが返され、次の呼び出しを行います。 軸 ID を取得するには getAxis()

ゲームパッド ボタンの押下を処理する

図 1 は、Android がどのようにキーコードと軸の値を物理オブジェクト ブロックに 多くのゲーム コントローラに搭載されています。

図 1. 汎用ゲーム コントローラのプロファイルです。

図の吹き出しについては、以下を参照してください。

ゲームパッドのボタンの押下によって生成される一般的なキーコードは次のとおりです。 BUTTON_A, BUTTON_B, BUTTON_SELECT, および BUTTON_START。ゲーム また、D-pad のクロスバーの中央が押されたときに DPAD_CENTER キーコードをトリガーします。お客様の ゲームが getKeyCode() を呼び出してキーコードを検査できる イベントやイベントなどの onKeyDown(), ゲームに関連するイベントを表す場合は 表示されます。表 1 は、最も一般的なものに対し推奨されるゲーム アクションを ゲームパッドのボタン。

表 1. ゲームパッドで推奨されるゲーム アクション できます。

ゲーム アクション ボタンのキーコード
メインメニューでゲームを開始する、ゲーム中に一時停止 / 一時停止解除する BUTTON_START*
メニューを表示する BUTTON_SELECT* および KEYCODE_MENU*
Android の戻るナビゲーション動作( ナビゲーションの設計 ご覧ください KEYCODE_BACK
メニュー内の前の項目に戻る BUTTON_B
選択を確認するか、メインのゲーム アクションを実行する BUTTON_ADPAD_CENTER

* ゲームの開始、選択、メニューの表示に依存してはならない ボタン] をタップします。

ヒント: 構成画面の提供を検討してください。 ユーザーがゲーム コントローラのマッピングをパーソナライズして、 作成します。

次のスニペットは、Cloud Storage バケットを onKeyDown()BUTTON_A を関連付けて、 DPAD_CENTER ボタンの押下 追加できます

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

注: Android 4.2(API)では、 レベル 17)以前では、 Android としての BUTTON_A デフォルトの [戻る] キーアプリがこれらの Android すべてのバージョンを メインのゲーム: BUTTON_A できます。現在の Android SDK を確認するには バージョンを確認するには、 Build.VERSION.SDK_INT の値。

十字キーの入力を処理する

4 方向の十字キー(D-pad)は、多くのゲームで一般的な物理的な操作になっている 使用できます。Android では、D-pad の上および下矢印の押下が次のようにレポートされます。 範囲のある AXIS_HAT_Y イベント 範囲は -1.0(上)から 1.0(下)までで、D-pad の LEFT または RIGHT キーとは -1.0 の範囲の AXIS_HAT_X イベント (左)から 1.0(右)に変更します。

D-pad の押下をキーコードでレポートするコントローラもあります。ゲームが D-pad の押下を考慮する場合は、ハット軸のイベントと D-pad を扱います。 入力イベントと同じものとして扱う必要があります(表 2 で推奨されているとおり)。

表 2. D-pad キーで推奨されるデフォルトのゲーム アクション ハット軸の値が示されています

ゲーム アクション D-pad のキーコード ハット軸のコード
上に移動 KEYCODE_DPAD_UP AXIS_HAT_Y(値が 0 から -1.0 の場合)
下に移動 KEYCODE_DPAD_DOWN AXIS_HAT_Y(値が 0 から 1.0 の場合)
左に移動 KEYCODE_DPAD_LEFT AXIS_HAT_X(値が 0 から -1.0 の場合)
右に移動 KEYCODE_DPAD_RIGHT AXIS_HAT_X(値が 0 から 1.0 の場合)

次のコード スニペットは、帽子をチェックするためのヘルパークラスを示しています。 入力イベントの軸とキーコードの値を使用して、D-pad の方向を決定します。

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

このヘルパークラスは、ゲーム内で処理を行う場所を問わず使用できます D-pad による入力( onGenericMotionEvent() または onKeyDown() あります。

例:

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.
    ...
}

ジョイスティックの動きを処理する

プレーヤーがゲーム コントローラのジョイスティックを動かすと、Android は 次を含む MotionEvent ACTION_MOVE アクション コードと更新された ジョイスティックの軸の位置を指定します。ゲームでは提供されたデータを MotionEvent: ジョイスティックが動いたかどうかを判断します。 重要な役割を果たします

ジョイスティックのモーション イベントでは、複数の動作サンプルがバッチ処理される場合があります。 1 つのオブジェクト内に格納しますMotionEvent オブジェクトには、以下が含まれます。 ジョイスティックの各軸の現在位置と、複数の履歴を 各軸の位置が示されます。アクション コード ACTION_MOVE を含むモーション イベント(ジョイスティックの動きなど)をレポートする場合、Android は 軸の値だけを使って効率性を高めます。軸の過去のデータは 現在の軸の値より古く、より新しい 以前のモーション イベントでレポートされた値。詳しくは、 詳しくは、MotionEvent のリファレンスをご覧ください。

履歴情報を使用して、ゲームをより正確にレンダリングできる ジョイスティックの入力に基づいてオブジェクトの動きを調整できます。宛先 現在値と過去の値を取得する場合は、 getAxisValue() または getHistoricalAxisValue()。また、過去 90 日間の過去の ジョイスティック イベントで getHistorySize()

次のスニペットは、Python や Curl で ジョイスティックの入力を処理するための onGenericMotionEvent() コールバック。まず 軸の過去の値を処理してから、現在の位置を処理します。

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

ジョイスティック入力を使用する前に、ジョイスティックが それに応じて軸の動きを計算します。ジョイスティックは通常 領域がフラット、つまり (0,0) 座標の付近にある値の範囲がある 軸を中心とみなす位置を指定します。レポートする軸の値について Android がフラットな領域に入る場合は、コントローラが 静止します(つまり、両軸に沿って静止します)。

以下のスニペットは、移動距離を計算するヘルパー メソッドを示しています。 確認できます。このヘルパーは、processJoystickInput() メソッドで呼び出します。 以下で説明します。

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

まとめると、ここで紹介するのはジョイスティックの動きを 必要があります。

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
}

より高度なゲーム コントローラをサポートするには、 機能を使用する場合は、次のベスト プラクティスに従ってください。

  • デュアル コントローラ スティックに対応する。多くのゲーム コントローラには、 左右両方のジョイスティックを操作します。左スティックは Android 水平方向の動きを AXIS_X イベントとしてレポート 垂直方向の動きを AXIS_Y イベントとして認識します。 右のスティックの場合、Android は水平方向の動きを AXIS_Z アクティビティと上下動 AXIS_RZ 件のイベント。注意すべき点は どちらのコントローラもコード内に残ります。
  • ショルダー トリガーの押下に対応する(ただし別の入力手段を提供する) メソッド)。左右ショルダーを持つコントローラもある 使用できます。これらのトリガーが存在する場合、Android は左トリガーの押下をレポートします。 AXIS_LTRIGGER イベント、 右トリガー押下 AXIS_RTRIGGER イベント。Android の場合 4.3(API レベル 18)では、API 呼び出しの AXIS_LTRIGGER は以下も報告しています: AXIS_BRAKE 軸の値が同じです。「 AXIS_RTRIGGER についても同様です。 AXIS_GAS。Android がすべてのアナログ トリガーをレポートする 0.0(リリース)~ 1.0(完全に押し込まれた)の正規化値で押します。× すべてのコントローラにトリガーがあるので、プレーヤーがトリガーできるようにすることを検討しましょう。 他のボタンと一緒にゲーム アクションを実行します。