Android: add multitouch support

This commit is contained in:
Sean 2014-05-25 11:02:45 -04:00
parent d0201335c6
commit 568f3248f3
2 changed files with 56 additions and 51 deletions

View File

@ -110,27 +110,26 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
@Override @Override
public boolean onTouch(View v, MotionEvent event) public boolean onTouch(View v, MotionEvent event)
{ {
// Determine the button state to apply based on the MotionEvent action flag. int pointerIndex = event.getActionIndex();
// TODO: This will not work when Axis support is added. Make sure to refactor this when that time comes
// The reason it won't work is that when moving an axis, you would get the event MotionEvent.ACTION_MOVE.
//
// TODO: Refactor this so we detect either Axis movements or button presses so we don't run two loops all the time.
//
int buttonState = (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)
? ButtonState.PRESSED : ButtonState.RELEASED;
// Check if there was a touch within the bounds of a drawable.
for (InputOverlayDrawableButton button : overlayButtons) for (InputOverlayDrawableButton button : overlayButtons)
{ {
if (button.getBounds().contains((int)event.getX(), (int)event.getY())) // Determine the button state to apply based on the MotionEvent action flag.
switch(event.getAction() & MotionEvent.ACTION_MASK)
{ {
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), buttonState); case MotionEvent.ACTION_DOWN:
} case MotionEvent.ACTION_POINTER_DOWN:
else case MotionEvent.ACTION_MOVE:
{ // If a pointer enters the bounds of a button, press that button.
// Because the above code only changes the state for the button that is being touched, sliding off the if (button.getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex)))
// button does not allow for it to be released. Release the button as soon as the touch coordinates leave NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), ButtonState.PRESSED);
// the button bounds. break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
// If a pointer ends, release the button it was pressing.
if (button.getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex)))
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), ButtonState.RELEASED); NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), ButtonState.RELEASED);
break;
} }
} }

View File

@ -22,7 +22,7 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
private final int[] axisIDs = {0, 0, 0, 0}; private final int[] axisIDs = {0, 0, 0, 0};
private final float[] axises = {0f, 0f}; private final float[] axises = {0f, 0f};
private final BitmapDrawable ringInner; private final BitmapDrawable ringInner;
private int trackid = -1; private int trackId = -1;
/** /**
* Constructor * Constructor
@ -62,43 +62,49 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
public void TrackEvent(MotionEvent event) public void TrackEvent(MotionEvent event)
{ {
int pointerIndex = event.getActionIndex(); int pointerIndex = event.getActionIndex();
if (trackid == -1)
switch(event.getAction() & MotionEvent.ACTION_MASK)
{ {
if (event.getAction() == MotionEvent.ACTION_DOWN) case MotionEvent.ACTION_DOWN:
if(getBounds().contains((int)event.getX(), (int)event.getY())) case MotionEvent.ACTION_POINTER_DOWN:
trackid = event.getPointerId(pointerIndex); if (getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex)))
} trackId = event.getPointerId(pointerIndex);
else break;
{ case MotionEvent.ACTION_UP:
if (event.getAction() == MotionEvent.ACTION_UP) case MotionEvent.ACTION_POINTER_UP:
{ if (trackId == event.getPointerId(pointerIndex))
if (trackid == event.getPointerId(pointerIndex))
{ {
axises[0] = axises[1] = 0.0f; axises[0] = axises[1] = 0.0f;
SetInnerBounds(); SetInnerBounds();
trackid = -1; trackId = -1;
}
} }
break;
} }
if (trackid == -1) if (trackId == -1)
return; return;
float touchX = event.getX();
float touchY = event.getY(); for (int i = 0; i < event.getPointerCount(); i++)
float maxY = this.getBounds().bottom; {
float maxX = this.getBounds().right; if (trackId == event.getPointerId(i))
touchX -= this.getBounds().centerX(); {
maxX -= this.getBounds().centerX(); float touchX = event.getX(i);
touchY -= this.getBounds().centerY(); float touchY = event.getY(i);
maxY -= this.getBounds().centerY(); float maxY = getBounds().bottom;
float maxX = getBounds().right;
touchX -= getBounds().centerX();
maxX -= getBounds().centerX();
touchY -= getBounds().centerY();
maxY -= getBounds().centerY();
final float AxisX = touchX / maxX; final float AxisX = touchX / maxX;
final float AxisY = touchY / maxY; final float AxisY = touchY / maxY;
axises[0] = AxisY;
this.axises[0] = AxisY; axises[1] = AxisX;
this.axises[1] = AxisX;
SetInnerBounds(); SetInnerBounds();
} }
}
}
public float[] getAxisValues() public float[] getAxisValues()
{ {