Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/205.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 具有奇怪坐标的最后一个MotionEvent_Android_Android Ndk - Fatal编程技术网

Android 具有奇怪坐标的最后一个MotionEvent

Android 具有奇怪坐标的最后一个MotionEvent,android,android-ndk,Android,Android Ndk,我们有益智游戏水果约会,已经有一段时间了。现在我们接到一名球员的报告,他不能触摸菜单上的任何项目。我们给他发了带屏幕调试的特别版本。我们专注于接触,他给了我们这个结果: 每个触摸事件都被截获。我为图片中的每一个“游戏触摸”分割了触摸事件集,左边有红线。每个游戏触摸事件都是这样的:向下(一个或多个拖动)-向上。奇怪的是,在触摸之前,触摸坐标中总是有很大的跳跃 我认为大多数拖动事件只是反弹,但总有至少一个会将坐标跳到左下角。随后,将使用这些不正确的坐标来执行后续事件。当我们检查球员是否在触地时开始

我们有益智游戏水果约会,已经有一段时间了。现在我们接到一名球员的报告,他不能触摸菜单上的任何项目。我们给他发了带屏幕调试的特别版本。我们专注于接触,他给了我们这个结果:

每个触摸事件都被截获。我为图片中的每一个“游戏触摸”分割了触摸事件集,左边有红线。每个游戏触摸事件都是这样的:向下(一个或多个拖动)-向上。奇怪的是,在触摸之前,触摸坐标中总是有很大的跳跃

我认为大多数拖动事件只是反弹,但总有至少一个会将坐标跳到左下角。随后,将使用这些不正确的坐标来执行后续事件。当我们检查球员是否在触地时开始触地的同一区域(参见区域参数)内触地时,则没有任何比赛,球员感觉游戏被卡住

报告错误的播放器有THL W200手机。我们以前在很多不同的物理设备上测试过,但从未遇到过这个问题

有人知道为什么会有这么奇怪坐标的运动事件(拖动)吗?你们有谁遇到过吗

我们的游戏是JNI,Java层很薄。MOVETATION事件从这样的视图发送到C++:

@Override
public boolean onTouchEvent(final MotionEvent aEvent) 
{
    final int action = aEvent.getAction();

    queueEvent(new Runnable()
    {
        int motionEvent = -1;

        public void run()
        {
            if (action == MotionEvent.ACTION_DOWN)
            {
                motionEvent = ANDROID_TOUCH_ACTION_DOWN;
            }
            else if (action == MotionEvent.ACTION_UP)
            {
                motionEvent = ANDROID_TOUCH_ACTION_UP;
            }
            else if (action == MotionEvent.ACTION_MOVE)
            {
                motionEvent = ANDROID_TOUCH_ACTION_MOVE;
            }

            SBCEngine.engine_on_touch((int) aEvent.getX(), (int) aEvent.getY(), motionEvent);
        }
    });
    return true;
}
class MotionEventRunnable implements Runnable
{
    private int mPointerID;
    private int mActionID;
    private int mX, mY;

  //-----------------------------------------------------
    public MotionEventRunnable(int aPointerID, int aActionID, int aX, int aY)
    {
        mPointerID = aPointerID;
        mActionID = aActionID;
        mX = aX;
        mY = aY;
    }

  //-----------------------------------------------------
    @Override
    public void run()
    {
        // send to native
        SBCEngine.engine_on_touch(mPointerID, mX, mY, mActionID);
    }
}

终于找到了解决方案,所以如果有人感兴趣

上述代码不安全。在处理事件之前,引用的事件对象可能会更改。这段代码取自《将厄运和地震移植到Android》一书,你们可以在网上找到类似的代码。直到昨天,它在所有测试过的设备上都有效。它在THL W200设备上失败

我将代码更改为:

@Override
public boolean onTouchEvent(final MotionEvent aEvent) 
{
    // get masked (not specific to a pointer) action
    int maskedAction = aEvent.getActionMasked();

    switch (maskedAction)
    {

    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_POINTER_DOWN:
    {
        // get pointer index from the event object
        int pointerIndex = aEvent.getActionIndex();
        // get pointer ID
        int pointerId = aEvent.getPointerId(pointerIndex);

        //Log.d("POINTER", "pointer down: ID = " + pointerId + " x=" + aEvent.getX(pointerIndex) + ", y = " + aEvent.getY(pointerIndex));
        queueEvent(new MotionEventRunnable(pointerId, maskedAction,
                        (int) aEvent.getX(pointerIndex),
                        (int) aEvent.getY(pointerIndex)));
        break;
    }

    case MotionEvent.ACTION_MOVE:
    { 
        // a pointer was moved
        int size = aEvent.getPointerCount();

        for (int i = 0; i < size; i++)
        {
            // Get the pointer ID and index
            int pointerId = aEvent.getPointerId(i);
            int pointerIndex = aEvent.findPointerIndex(pointerId);

            //Log.d("POINTER", "pointer move: ID = " + pointerId + " x=" + aEvent.getX(pointerIndex) + ", y = " + aEvent.getY(pointerIndex));
            queueEvent(new MotionEventRunnable(pointerId, maskedAction,
                    (int) aEvent.getX(pointerIndex),
                    (int) aEvent.getY(pointerIndex)));
        }
        break;
    }

    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_POINTER_UP:
    case MotionEvent.ACTION_CANCEL:
    {
        // get pointer index from the event object
        int pointerIndex = aEvent.getActionIndex();
        // get pointer ID
        int pointerId = aEvent.getPointerId(pointerIndex);

        //Log.d("POINTER", "pointer up: ID = " + pointerId + " x=" + aEvent.getX(pointerIndex) + ", y = " + aEvent.getY(pointerIndex));
        queueEvent(new MotionEventRunnable(pointerId, maskedAction,
                (int) aEvent.getX(pointerIndex),
                (int) aEvent.getY(pointerIndex)));
        break;
    }
    }

    return true;
}
代码更复杂,因为它还处理多点触摸,但关键是我缓存了所有必需的值:指针id、动作、x和y。它解决了我的问题