5

我需要有两种不同的行为,一种用于 D-pad,另一种用于模拟操纵杆(在同一个游戏手柄上)。

问题是在onGenericMotionEvent回调中,两者都有相同的信息,MotionEvent我无法区分它们。

// d-pad
MotionEvent { action=ACTION_MOVE, id[0]=0, x[0]=-1.5259255E-5, y[0]=-1.5259255E-5, toolType[0]=TOOL_TYPE_UNKNOWN, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=151637936, downTime=0, deviceId=5, source=0x1000010 }

// analog joystick
MotionEvent { action=ACTION_MOVE, id[0]=0, x[0]=0.64507514, y[0]=0.710811, toolType[0]=TOOL_TYPE_UNKNOWN, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=151650802, downTime=0, deviceId=5, source=0x1000010 }

是否可以识别正在使用哪种输入?如何?

4

3 回答 3

4

我遇到了同样的问题,我不得不深入研究这个有用的 Git 用户的项目,以弄清楚他是如何做到的。区分不同操纵杆(和方向键)的方法是使用每个方向的特定

如果您非常仔细地阅读了Android 文档页面(我没有注意到它),它确实显示了您如何区分各种操纵杆及其方向:

不同轴/标签的 Android 文档

此图像显示左操纵杆使用轴AXIS_XAXIS_Y,而右操纵杆使用AXIS_ZAXIS_RZ。对于方向键,我使用了 AXIS_HAT_XAXIS_HAT_Y。我的代码(在 Kotlin 中)中的以下代码段显示了如何单独访问这些代码段:

注意:我还将搜索栏设置为 0-100 的范围,这就是为什么我在processJoystickInput().

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

    val inputDevice = event.device

    val newJoystickValues = floatArrayOf(
            getCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos),
            getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos),
            getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos),
            getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos),
            getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos),
            getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos))

    // Update based on the new x and y values
    val throttleSeekBar = findViewById<SeekBar>(R.id.throttle_seekBar)
    val yawSeekBar = findViewById<SeekBar>(R.id.yaw_seekBar)
    val pitchSeekBar = findViewById<SeekBar>(R.id.pitch_seekBar)
    val rollSeekBar = findViewById<SeekBar>(R.id.roll_seekBar)
    val dpadXSeekBar = findViewById<SeekBar>(R.id.dpadX_seekBar)
    val dpadYSeekBar = findViewById<SeekBar>(R.id.dpadY_seekBar)

    // Convert the float range (-1.00 to 1.00) to Int (0 to 100)
    yawSeekBar.progress = ((newJoystickValues[0] + 1) * 50).toInt()
    throttleSeekBar.progress = ((newJoystickValues[1] + 1) * 50).toInt()
    rollSeekBar.progress = ((newJoystickValues[2] + 1) * 50).toInt()
    pitchSeekBar.progress = ((newJoystickValues[3] + 1) * 50).toInt()
    dpadXSeekBar.progress = ((newJoystickValues[4] + 1) * 50).toInt()
    dpadYSeekBar.progress = ((newJoystickValues[5] + 1) * 50).toInt()
}

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)
    }
}
于 2019-10-22T18:50:29.320 回答
0

来自 Android 文档(https://developer.android.com/training/game-controllers/controller-input):

Android 将 D-pad UP 和 DOWN 按下报告为 AXIS_HAT_Y 事件,范围从 -1.0(上)到 1.0(下),D-pad LEFT 或 RIGHT 按下作为 AXIS_HAT_X 事件,范围从 -1.0(左)到 1.0(正确的)。

一些控制器改为使用键代码报告 D-pad 按下。如果您的游戏关心 D-pad 按下,您应该将帽子轴事件和 D-pad 键代码视为相同的输入事件,如表 2 中建议的那样。

我使用过的两个控制器(NVIDIA SHIELD 蓝牙和 Microsoft XBOX360 有线)都生成 AXIS_HAT_* 运动事件。

于 2018-09-19T19:25:40.933 回答
0

查看您提供的信息,它们看起来来自同一来源,即操纵杆 (0x1000010)。您可以在Input Device对象上查看这些信息。

以下信息来自处理控制器操作

要验证连接的输入设备是否为游戏控制器,请调用getSources()以获取该设备支持的输入源类型的组合位字段。

源类型SOURCE_GAMEPAD表示输入设备具有游戏手柄按钮(例如,BUTTON_A)。请注意,尽管大多数游戏手柄通常具有方向控制,但此源类型并未严格指示游戏控制器是否具有方向键按钮。

源类型SOURCE_DPAD表示输入设备具有方向键按钮(例如,DPAD_UP)。

源类型SOURCE_JOYSTICK表示输入设备具有模拟控制杆(例如,记录沿AXIS_X和移动的操纵杆AXIS_Y)。

您可能还需要检查Supporting Multiple Controller Input

于 2016-01-03T14:23:40.307 回答