如何区分方向键运动和操纵杆运动? [英] How to differentiate a D-pad movement from a Joystick movement?

查看:43
本文介绍了如何区分方向键运动和操纵杆运动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要有两种不同的行为,一种用于方向键,另一种用于模拟操纵杆(在同一个游戏手柄上).

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

//方向键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 }//模拟操纵杆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 }

是否可以确定正在使用哪种输入?怎么样?

解决方案

我遇到了同样的问题,我不得不深入研究

此图显示左侧操纵杆使用轴AXIS_XAXIS_Y,而右侧操纵杆使用AXIS_ZAXIS_RZ.对于方向键,我使用了 AXIS_HAT_XAXIS_HAT_Y.我的代码(在 Kotlin 中)中的以下片段显示了如何单独访问其中的每一个:

注意:我也将搜索条设置为 0-100 的范围,这就是为什么我在 processJoystickInput() 底部有转换数学.

 私有乐趣 processJoystickInput(event: MotionEvent, historyPos: Int) {val inputDevice = event.deviceval 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(事件,输入设备,MotionEvent.AXIS_HAT_Y,historyPos))//根据新的 x 和 y 值更新valthrottleSeekBar = findViewById(R.id.throttle_seekBar)val yawSeekBar = findViewById(R.id.yaw_seekBar)val pitchSeekBar = findViewById(R.id.pitch_seekBar)val rollSeekBar = findViewById(R.id.roll_seekBar)val dpadXSeekBar = findViewById(R.id.dpadX_seekBar)val dpadYSeekBar = findViewById(R.id.dpadY_seekBar)//将浮点范围(-1.00 到 1.00)转换为 Int(0 到 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()}覆盖 fun onGenericMotionEvent(event: MotionEvent): Boolean {//检查事件是否来自游戏控制器返回 if (event.source and(InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK&&event.action == MotionEvent.ACTION_MOVE) {//处理从开始的动作//批次中最早的历史位置(0 直到 event.historySize).forEach { i ->//处理历史位置 i 的事件processJoystickInput(event, i)}//处理batch中的当前运动样本(位置-1)processJoystickInput(事件,-1)真的} 别的 {super.onGenericMotionEvent(事件)}}

I need to have two different behaviors, one for D-pad and another for the analog Joystick (on the same gamepad).

The problem is that on the onGenericMotionEvent callback, both have the same information on the MotionEvent and I am not able to distinguish them.

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

Is it possible to identify which kind of input is being used? How?

解决方案

I ran into this same issue, and I had to dig through this helpful Git user's project to figure out how he did it. The way you differentiate between the different joysticks (and the D-pad) is to use each direction's specific axis.

If you read the Android documentation's page very carefully (I didn't pick up on it), it does show how you can differentiate between the various joysticks and their directions:

This image shows that the left joystick uses axes AXIS_X and AXIS_Y, whereas the right joystick uses AXIS_Z and and AXIS_RZ. For the D-pad, I used AXIS_HAT_X and AXIS_HAT_Y. The following snippet from my code (in Kotlin) shows how you can access each of these individually:

Note: I also had my seek bars set to a range of 0-100, which is why I have the conversion math at the bottom of 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)
    }
}

这篇关于如何区分方向键运动和操纵杆运动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆