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;
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), ButtonState.RELEASED); 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);
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,42 +62,48 @@ 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;
{ SetInnerBounds();
axises[0] = axises[1] = 0.0f; trackId = -1;
SetInnerBounds(); }
trackid = -1; break;
} }
if (trackId == -1)
return;
for (int i = 0; i < event.getPointerCount(); i++)
{
if (trackId == event.getPointerId(i))
{
float touchX = event.getX(i);
float touchY = event.getY(i);
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 AxisY = touchY / maxY;
axises[0] = AxisY;
axises[1] = AxisX;
SetInnerBounds();
} }
} }
if (trackid == -1)
return;
float touchX = event.getX();
float touchY = event.getY();
float maxY = this.getBounds().bottom;
float maxX = this.getBounds().right;
touchX -= this.getBounds().centerX();
maxX -= this.getBounds().centerX();
touchY -= this.getBounds().centerY();
maxY -= this.getBounds().centerY();
final float AxisX = touchX / maxX;
final float AxisY = touchY/maxY;
this.axises[0] = AxisY;
this.axises[1] = AxisX;
SetInnerBounds();
} }
public float[] getAxisValues() public float[] getAxisValues()