首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >您如何使用MotionEvent.ACTION_POINTER_INDEX_SHIFT?

您如何使用MotionEvent.ACTION_POINTER_INDEX_SHIFT?
EN

Stack Overflow用户
提问于 2013-01-18 03:08:27
回答 3查看 14.3K关注 0票数 6

我一直在做一个游戏,我试图让控制器,没有太复杂,为此,我需要跟踪2个输入(手指):1火按钮和移动键。(上,下,左,右)

这就是问题所在:手指1下降,手指2下降,手指1上升以为是2,然后手指2上升以为是1。

代码语言:javascript
复制
D/Controlls(18849): Action Down 1
D/Controlls(18849): Coordinates 267.7908 415.24274
D/Controlls(18849): Action Pointer Down 2
D/Controlls(18849): Coordinates 281.11423 417.23993
D/Controlls(18849): Action Pointer UP 1
D/Controlls(18849): Coordinates 272.7869 419.23718
D/Controlls(18849): Action UP 2
D/Controlls(18849): Coordinates 1148.103 439.20947

这是处理两个输入的OnTouchEvent的代码:

代码语言:javascript
复制
@Override
public boolean onTouchEvent(MotionEvent event) {
    int index = event.getActionIndex();
    int pointerId = event.getPointerId(index);
    int action = event.getActionMasked();

    int oldX, oldY;

    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
        {
            hero.moveControlls((int)event.getX(), (int)event.getY());
            Log.d("Controlls", "Action Down "+ pointerId);
            Log.d("Controlls", "Coordinates "+ event.getX() + " "+ event.getY());
            break;
        }

        case MotionEvent.ACTION_UP:
        {
            hero.setScreenTouching(false);
            Log.d("Controlls", "Action UP "+ pointerId);
            Log.d("Controlls", "Coordinates "+ event.getX() + " "+ event.getY());
            break;
        }

        case MotionEvent.ACTION_POINTER_DOWN:
        {
            Log.d("Controlls", "Action Pointer Down "+ pointerId);
            Log.d("Controlls", "Coordinates "+ event.getX() + " "+ event.getY());                   
            break;
        }

        case MotionEvent.ACTION_POINTER_UP:
        {
            Log.d("Controlls", "Action Pointer UP "+ pointerId);
            Log.d("Controlls", "Coordinates "+ event.getX() + " "+  event.getY());
            break;
        }
    }
    return true;
}

现在,我查阅了这些例子,但无法理解它们。我在API中查找了MotionEvent,它说要使用我不知道如何使用的$ACTION_POINTER_INDEX_SHIFT$,因为他们没有一个示例或其他东西来使它更容易理解。对怎么做有什么帮助吗?

EN

回答 3

Stack Overflow用户

发布于 2013-02-22 17:50:50

每当次级指针下降或上升时,就会触发ACTION_POINTER_DOWN和ACTION_POINTER_UP。如果屏幕上已经有一个指针,并且一个新的指针掉了,那么您将收到ACTION_POINTER_DOWN而不是ACTION_DOWN。如果指针上升,但至少仍有一个触摸屏幕,则将接收ACTION_POINTER_UP而不是ACTION_UP。

ACTION_POINTER_DOWN和ACTION_POINTER_UP事件在操作值中编码额外的信息。使用ACTION_POINTER_INDEX_MASK,ANDing给出了动作常量,而ANDing给出了指针向上或向下的索引。

提取离开触摸传感器的指针的索引的最佳方法。

MotionEvent.ACTION_POINTER_INDEX_SHIFT; = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> pointerIndex

我将相应地修改您的代码如下:

代码语言:javascript
复制
case MotionEvent.ACTION_POINTER_UP:
{
    int index = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
    int pointId = event.getPointerId(index);
    Log.d("Controlls", "Action Pointer UP "+ pointerId);
    Log.d("Controlls", "Coordinates "+ event.getX(index) + " "+  event.getY(index));
    break;
}
票数 13
EN

Stack Overflow用户

发布于 2013-01-18 03:32:49

我认为混淆之处可能是getX()getY()方法总是返回指针的坐标(第一个/唯一一个向下)。因此,您的日志指1中的前三个事件是主事件,而在最后一个事件中,只剩下了两个手指,因此它成为主事件。

如果要正确地跟踪两个手指的事件,则需要使用getX(int)getY(int);使用指针索引作为参数的版本,这样就可以离散地获取每个事件中每个手指的坐标。请注意,如果每个手指的索引以不同的顺序向下和向上移动,则它们的索引可能会发生变化,但是给定的手指始终具有相同的指针Id。

一种很好的方法是检查每个事件中的指针数量(例如getPointerCount())。用一个手指,索引0是有效的;用两个手指,索引0和1是有效的。获取每个有效指针的坐标,然后使用getPointerId()确定每个坐标对应该匹配的手指。

编辑

为了返回右指针的坐标,您发布的源代码最简单的修改是将索引添加到辅助指针的参数中,如下所示:

代码语言:javascript
复制
int index = event.getActionIndex();
int pointerId = event.getPointerId(index);
int action = event.getActionMasked();

int oldX, oldY;

switch (event.getActionMasked()) {
    case MotionEvent.ACTION_DOWN:
    {
        hero.moveControlls((int)event.getX(), (int)event.getY());
        Log.d("Controlls", "Action Down " + pointerId);
        Log.d("Controlls", "Coordinates "+ event.getX() + " "+ event.getY());
        break;
    }

    case MotionEvent.ACTION_UP:
    {
        hero.setScreenTouching(false);
        Log.d("Controlls", "Action UP "+ pointerId);
        Log.d("Controlls", "Coordinates "+ event.getX() + " "+ event.getY());
        break;
    }

    case MotionEvent.ACTION_POINTER_DOWN:
    {
        Log.d("Controlls", "Action Pointer Down "+ pointerId);
        Log.d("Controlls", "Coordinates "+ event.getX(index) + " "+ event.getY(index));
        break;
    }

    case MotionEvent.ACTION_POINTER_UP:
    {
        Log.d("Controlls", "Action Pointer UP "+ pointerId);
        Log.d("Controlls", "Coordinates "+ event.getX(index) + " "+  event.getY(index));
        break;
    }
}

这将使数据更符合您期望看到的内容。

票数 2
EN

Stack Overflow用户

发布于 2014-01-14 21:15:28

如果按与按不同的顺序释放指针(使用多点触摸时可能发生的情况),上述代码可能会失败。我发现下面的代码适用于3个指针,按下然后释放的顺序并不重要:

代码语言:javascript
复制
    case MotionEvent.ACTION_UP: // for single touch
    case MotionEvent.ACTION_POINTER_UP: // when order of touch and release is the same
    case MotionEvent.ACTION_POINTER_UP + ((1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT)): // for any order of two pointers
    case MotionEvent.ACTION_POINTER_UP + ((2 << MotionEvent.ACTION_POINTER_INDEX_SHIFT)): // for any order of three pointers
    case MotionEvent.ACTION_OUTSIDE: // when moving touch out of the view
    case MotionEvent.ACTION_CANCEL: // when canceling touch (eg by home button)
    // some code to support releasing pointers
    break;

请记住,case语句旁边必须是一个常量值,因此不能基于event.getMotion()计算值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14391818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档