2013-01-18 1 views
3

나는 게임에서 일해 왔고 나는 컨트롤러를 만들려고 노력하고있다. 너무 복잡하고이 작업을 수행하기 위해 2 개의 입력 (손가락)을 추적해야한다 : 1 발사 버튼과 이동 키. (위, 아래, 손가락 2가 다운 손가락 하나가 다운 손가락 1은 2이다 생각하고 2 손가락은 1어떻게 MotionEvent.ACTION_POINTER_INDEX_SHIFT를 사용합니까?

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 

이가이다의 생각을 상승 상승 : 왼쪽, 오른쪽)

이 문제입니다 2 개의 입력을 처리하는 OnTouchEvent 코드 :

@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 $를 사용한다고한다. 이해하기 쉽도록 예제가 없기 때문이다. 이 작업을 수행하는 방법에 대한 도움이 필요하십니까?

답변

2

나는 혼란이 방법 getX()getY() 항상 포인터 (첫 번째/하나 개의 아래)의 좌표를 반환하는 것이 될 수있다 생각합니다. 따라서 로그 핑거 1의 처음 세 가지 이벤트가 기본 이벤트이며, 마지막으로 손가락 2 만 남아 있으므로 기본 이벤트가됩니다.

두 손가락의 이벤트를 올바르게 추적하려면 getX(int)getY(int)을 사용해야합니다. 포인터 인덱스를 매개 변수로 사용하는 버전이므로 각 이벤트의 각 손가락에 대한 좌표를 개별적으로 가져올 수 있습니다. 각 손가락의 색인은 다른 순서로 아래 위로 올라가는 경우 변경 될 수 있지만 주어진 손가락은 항상 동일한 포인터 ID를 갖습니다.

좋은 방법은 각 이벤트의 포인터 수를 확인하는 것입니다 (예 : getPointerCount()). 한 손가락으로 인덱스 0이 유효합니다. 두 손가락으로 인덱스 0과 인덱스 1이 유효합니다. 각 유효한 포인터에 대한 좌표를 가져온 다음 getPointerId()을 사용하여 각 좌표 쌍이 일치해야하는 손가락을 찾습니다.

편집 당신이 바로 포인터의 좌표를 반환 게시 한 소스 코드에 대한 간단한 수정, 이차 포인터의 매개 변수에 인덱스를 추가과 같이하는 것입니다

:

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

예상되는 정보와 함께 더 많은 데이터를 기록해야합니다.

+0

나는 당신이 말하는 것을 얻지 만 여전히 구현할 수 없다. –

+0

귀하의 switch 문을 수정했습니다. – Devunwired

+0

비슷한 문제가 있습니다. MotionEvent.ACTION_POINTER_INDEX_MASK (이 주제의 모든 예에서 나타납니다)로 조치를 "ANDing"하고 교대의 목적은 무엇인지 설명해 주시겠습니까? 나는 또한이 가면이 무엇인지에 대해 명확하지 않으며 문서는 비밀 스럽다. 나는 그것과 감상을 더 명확하게하기 위해 크게 감사 할 것이다. 감사! – Rookatu

10

ACTION_POINTER_DOWN 및 ACTION_POINTER_UP은 보조 포인터가 아래로 오르거나 올라갈 때마다 발생합니다. 이미 화면에 포인터가 있고 새 포인터가 내려 가면 ACTION_DOWN 대신 ACTION_POINTER_DOWN을 받게됩니다. 포인터가 올라가고 있지만 여전히 화면을 터치하는 사람이 하나라도 있으면 ACTION_UP 대신 ACTION_POINTER_UP을 받게됩니다.

ACTION_POINTER_DOWN 및 ACTION_POINTER_UP 이벤트는 조치 값에 추가 정보를 인코딩합니다. MotionEvent.ACTION_MASK와 AND 연산은 우리가 ACTION_POINTER_INDEX_MASK와이 우리에게 내려

터치 센서를 왼쪽 포인터의 인덱스를 추출하는 가장 좋은 방법을 갔다 또는 포인터의 인덱스를 제공 AND 연산 동안 작업 일정을 제공합니다.

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

나는 아래와 같이 따라 코드를 변경합니다 : 당신이 (멀티 터치를 사용하는 경우 수도가 발생하는)를 눌러보다 다른 순서로 포인터를 놓으면

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; 
} 
+0

awesome. 고마워요! –

+1

MotionEventCompat.getActionIndex를 사용하는 것이 조금 깔끔합니다. – Delyan

0

위의 코드가 실패 할 수 있습니다.

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; 

당신이 값을 기준으로 계산하지 수 있도록 상수 값을해야 그 다음 경우에 문을 기억 나는 다음 코드는 3 포인터 작동 한 다음 Enter 키를 눌러 해제의 순서가 문제가되지 않는 것으로 확인 event.getMotion().