0

我的游戏中有一个奇怪的问题。我正在使用 2 个操纵杆,一个用于射击/瞄准,一个用于移动我的角色。出于某种原因,我的多点触控方法一次只记录一个动作。当我按下时,第二个指针被注册,但我ACTION_MOVE只适用于第一个指针。这很奇怪,因为这意味着它确实需要多于一个指针,但它不能同时移动多于一个指针。我在 gamedev.stackexchange 上问过这个问题,它已经活跃了大约一周,得到了几个答案,但没有任何东西可以让它 100% 工作。我已经自己尝试了几个小时。

onTouch 方法的代码:

    //global variables
    private int movePointerId = -1;
    private int shootingPointerId = -1;

public void update(MotionEvent event) {

    if (event == null && lastEvent == null) {
        return;
    } else if (event == null && lastEvent != null) {
        event = lastEvent;
    } else {
        lastEvent = event;
    }   

    // grab the pointer id 
    int action = event.getAction();
    int actionCode = action & MotionEvent.ACTION_MASK;
    int actionIndex = event.getActionIndex();
    int pid = action >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
    int x = (int) event.getX(pid);
    int y = (int) event.getY(pid); 
    String actionString = null;


    switch (actionCode)
    {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:

            actionString = "DOWN";
            try{
                if(x > 0 && x < steeringxMesh + (joystick.get_joystickBg().getWidth() * 2)
                   && y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
                        movingPoint.x = x;
                        movingPoint.y = y;
                        movePointerId = pid;
                        dragging = true;
                        //checks if Im pressing the joystick used for moving
                    }
                 else if(x > shootingxMesh - (joystick.get_joystickBg().getWidth()) && x < panel.getWidth()
                         && y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
                        shootingPoint.x = x;
                        shootingPoint.y = y;
                        shootingPointerId = pid;
                        shooting=true;
                        //checks if Im pressing the joystick used for shooting
                    }
                }catch(Exception e){

                }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_OUTSIDE:

           if( pid == movePointerId ){
              movePointerId = -1;
              dragging = false;
              }
           else if( pid == shootingPointerId ){
              shootingPointerId = -1;
              shooting=false;
              }
            actionString = "UP";
            break;  
        case MotionEvent.ACTION_MOVE: // this is where my problem is

          if( pid == movePointerId ) {
                        movingPoint.x = x;
                        movingPoint.y = y;
          } else if( pid == shootingPointerId ) {
                        shootingPoint.x = x;
                        shootingPoint.y = y;
          }
                actionString = "MOVE";
                break;

    }

如果我打印actionStringpid显示移动时它只检查pid=0,但是当我按下 ( ACTION_POINTER_DOWN) 时,我可以看到它确实注册了另一个pid,这真的让我感到困惑。

为了更清楚起见,当我按下第二个指针时,例如我的射击杆,它会占据我按下的位置,即使我同时移动另一个操纵杆,但它会一直停留在那里直到我放开了另一个操纵杆。进一步证明它确实注册了超过 1 次触摸和超过 1 次pid

如果您需要任何进一步的解释,请告诉我。

4

3 回答 3

2

我对您的代码进行了一些更改,我认为应该可以解决问题。至少它对我来说很好......

    //global variables 
private int movePointerId = -1; 
private int shootingPointerId = -1; 

public void update(MotionEvent event) { 

if (event == null && lastEvent == null) { 
    return; 
} else if (event == null && lastEvent != null) { 
    event = lastEvent; 
} else { 
    lastEvent = event; 
}    

// grab the pointer id  
int action = event.getAction(); 
int actionCode = action & MotionEvent.ACTION_MASK; 
int pid = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int fingerid = event.getPointerId(pid);

//int actionIndex = event.getActionIndex(); 
//int pid = action >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
int x = (int) event.getX(pid); 
int y = (int) event.getY(pid);  
String actionString = null; 


switch (actionCode) 
{ 
    case MotionEvent.ACTION_DOWN: 
    case MotionEvent.ACTION_POINTER_DOWN: 

        actionString = "DOWN"; 
        try{ 
            if(x > 0 && x < steeringxMesh + (joystick.get_joystickBg().getWidth() * 2) 
               && y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){ 
                    movingPoint.x = x; 
                    movingPoint.y = y; 
                    //movePointerId = pid; 
                    movePointerId = fingerid; 
                    dragging = true; 
                    //checks if Im pressing the joystick used for moving 
                } 
             else if(x > shootingxMesh - (joystick.get_joystickBg().getWidth()) && x < panel.getWidth() 
                     && y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){ 
                    shootingPoint.x = x; 
                    shootingPoint.y = y; 
                    //shootingPointerId = pid; 
                    shootingPointerId = fingerid; 
                    shooting=true; 
                    //checks if Im pressing the joystick used for shooting 
                } 
            }catch(Exception e){ 

            } 
        break; 
    case MotionEvent.ACTION_UP: 
    case MotionEvent.ACTION_POINTER_UP: 
    case MotionEvent.ACTION_CANCEL: 
    case MotionEvent.ACTION_OUTSIDE: 

       if( fingerid == movePointerId ){  //changed this line
          movePointerId = -1; 
          dragging = false; 
          } 
       else if( fingerid == shootingPointerId ){  //changed this line
          shootingPointerId = -1; 
          shooting=false; 
          } 
        actionString = "UP"; 
        break;   
    case MotionEvent.ACTION_MOVE: // this is where my problem is 

      if( fingerid == movePointerId ) { //changed this line
                    movingPoint.x = x; 
                    movingPoint.y = y; 
      } else if( fingerid == shootingPointerId ) { //changed this line
                    shootingPoint.x = x; 
                    shootingPoint.y = y; 
      } 
            actionString = "MOVE"; 
            break; 

} 

这样做的原因是,在某些设备上,当您松开一根手指时,指针 ID 可能会发生变化。例如,第一根手指接收到指针 id 1,然后按下第二根手指,接收到指针 id 2,然后如果松开手指 1,则手指 2 的指针 id 可能会变为 1。这听起来可能有点混乱,但你应该避免上面这个手指ID的问题。

祝你好运。

于 2012-09-26T00:22:39.477 回答
1

指针有两个不同的属性可用于识别它们:

  • index:它的范围从 0 到比getPointerCount()返回的值小一。它仅在当前事件的处理过程中有效

  • id:此属性唯一标识指针,并保证指针在其整个生命周期内保持不变

在您的代码中,您没有正确检索索引ID信息。基本上,您使用索引来识别多个事件中的指针,这是完全错误的,因为索引可能会有所不同,这就是您在应用程序中遇到的情况。简而言之,您应该使用 id 来识别指针

正如我所提到的,他们检索索引id的方式是错误的。检索这些属性的正确方法是:

int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
             MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pid = event.getPointerId(index);

您可以参考此处了解更多信息:MotionEvent | 安卓开发者

于 2013-12-14T18:00:14.473 回答
0

private int movePointerId = -1;并且private int shootingPointerId = -1;,它们不应该具有不同的值吗?我真的不知道,但是一旦我遇到问题,我就更改了值并且它起作用了。

于 2012-09-25T20:52:00.283 回答