I've been working in a game and I'm trying to make the controllers, nothing too complicated and to do this I need to track 2 inputs(fingers): 1 the fire button and move keys.(up, down, left, right)
This is the problem: finger 1 is down, finger 2 is down, finger 1 goes up thinking it's 2 and then finger 2 goes up thinking it's 1.
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
This is the code for the OnTouchEvent which handles the 2 inputs:
@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;
}
Now, I looked up in the examples, but could not understand them. I looked up MotionEvent in the API and it says to use $ACTION_POINTER_INDEX_SHIFT$ which I have no clue how to use, because they don't have an example or something to make it understood easier. Any help on how to do this?
ACTION_POINTER_DOWN and ACTION_POINTER_UP are fired whenever a secondary pointer goes down or up. If there is already a pointer on the screen and a new one goes down, you will receive ACTION_POINTER_DOWN instead of ACTION_DOWN. If a pointer goes up but there is still at least one touching the screen, you will receive ACTION_POINTER_UP instead of ACTION_UP.
The ACTION_POINTER_DOWN and ACTION_POINTER_UP events encode extra information in the action value. ANDing it with MotionEvent.ACTION_MASK gives us the action constant while ANDing it with ACTION_POINTER_INDEX_MASK gives us the index of the pointer that went up or down
The best way to extract the index of the pointer that left the touch sensor.
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
I would change your code accordingly like below:
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;
}