I'm having some trouble with handling multi-touch in android game:
when I touch the screen with three or more fingers, remove them, and touch it again I'm getting this error:
java.lang.IllegalArgumentException: pointerIndex out of range, which occurs in this line of code in onTouchEvent : x = (int) event.getX(event.findPointerIndex(a));
Here is the code
#Override
public boolean onTouchEvent(MotionEvent event)
{
//touch positions
int x, y;
//number of touched areas
int num = event.getPointerCount();
//masked touch action
int action = event.getActionMasked();
if(1 < num && num < 3)
{
for (int a = 0; a < num; a++)
{
x = (int) event.getX(event.findPointerIndex(a));
y = (int) event.getY(event.findPointerIndex(a));
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
{
if(y > screenY/2) point1.set(x, y);
if(y < screenY/2) point2.set(x, y);
}
}
}
}
else
{
x = (int) event.getX();
y = (int) event.getY();
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
{
if(y > screenY/2) point1.set(x, y);
if(y < screenY/2) point2.set(x, y);
}
}
}
return true;
}
Related
I am trying to create a simple find the difference game in android by using touch coordinates of each difference but when I note down the coordinates in one device then it's working fine. and when I use some other device those coordinates aren't there. so is there any way in which I can work this out
here's some of the code:
image1.setOnTouchListener(new View.OnTouchListener() {
#SuppressLint({"ClickableViewAccessibility", "UseCompatLoadingForDrawables"})
#Override
public boolean onTouch(View v, MotionEvent event) {
int X =(int) event.getX();
int Y =(int) event.getY();
String msg = "Coordinates are " + X + "and" + Y;
int eventAction = event.getAction();
if(eventAction == MotionEvent.ACTION_DOWN){
int x = (int) event.getX();
int y = (int) event.getY();
if(checkPoint(X,Y) == true){
Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
}
private boolean checkPoint(int x, int y) {
int touchX = (int) x;
int touchY = y;
float centerX = 950, centerY = 600;
float radius = 100;
if (Math.pow(centerX-touchX , 2)
+ Math.pow(centerY-touchY , 2) < Math.pow(radius, 2))
{
Toast.makeText(MainActivity.this,"points inside circe",Toast.LENGTH_SHORT).show();
return true;
}
else
{
Toast.makeText(MainActivity.this,"points outside circle",Toast.LENGTH_SHORT).show();
return false;
}
return false;
}
When I open my app on the left top corner appears image, when I touch it image starts to move towards bottom right corner. Now when I stop moving my finger (while touching image) image stops as well, how to make image move without interruption?
img.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int X = (int) event.getX();
int Y = (int) event.getY();
int action = event.getAction();
imgX += 1;
imgY += 1;
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
if (X >= 0 && X <= img.getWidth() && Y >= 0 && Y <= img.getHeight()) {
img.setX(imgX);
img.setY(imgY);
}
else {
finish();
}
break;
case MotionEvent.ACTION_UP:
finish();
break;
}
return true;
}
});
I know how to set ontouchlistener on a button. I can touch linearlayout and move my finger on it but that finger does not detect the touch on buttons. it seems as I touch the buttons but actually I am touching linearlayout. how can I touch the buttons placed on linear layout in sequence.
layoutVertical.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int actionPeformed = event.getAction();
switch (actionPeformed) {
case MotionEvent.ACTION_DOWN: {
final float x = event.getX();
final float y = event.getY();
lastXAxis = x;
lastYAxis = y;
textView2.setText("Button pressed");
//buttons[0][0].setBackgroundColor(Color.RED);
for(int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
}
}
break;
}
case MotionEvent.ACTION_MOVE: {
final float x = event.getX();
final float y = event.getY();
final float dx = x - lastXAxis;
final float dy = y - lastYAxis;
ed4 = (EditText) findViewById(R.id.editText4);
xAxis += dx;
yAxis += dy;
ed4.setText(Float.toString(yAxis));
break;
}
case MotionEvent.ACTION_UP: {
textView2.setText("released");
buttons[0][0].setBackgroundColor(Color.WHITE);
GradientDrawable drawable = new GradientDrawable();
//drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setStroke(2, Color.MAGENTA);
drawable.setColor(Color.WHITE);
buttons[rows][cols].setBackgroundDrawable(drawable);
mp.pause();
}
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
}
return true;
}
});
I am using following code to drag a View across the screen
tweatBtn.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
float currX,currY;
int action = event.getAction();
switch (action ) {
case MotionEvent.ACTION_DOWN:
{
mPrevX = event.getRawX();
mPrevY = event.getRawY();
btnPrevX = tweatBtn.getX();
btnPrevY = tweatBtn.getY();
break;
}
case MotionEvent.ACTION_MOVE:
{
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth() + 80; // deprecated
int height = display.getHeight(); // deprecated
currX = event.getRawX();
currY = event.getRawY();
if(tweatBtn.getY() > 80 && tweatBtn.getX() > 0 && tweatBtn.getX() < width)
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
else
{
if((btnPrevY + currY - mPrevY) > 70 && (btnPrevX + currX - mPrevX) > -10 && tweatBtn.getX() < (width - 10))
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
});
}
It works fine but sometimes when i lift the Finger it automatically triggers click.How can i improve?
You are returning always false at the end of the code. Which means the touchListener you have set is not handling the touch. Because of if it, View will consider any normal touch as click. What you should do is return True, when the view is dragged, else you should return False
boolean dragged = false;
ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
int minTouchSlop = viewConfiguration.getScaledTouchSlop();
.....
public boolean onTouch(View v, MotionEvent event)
{
float currX,currY;
int action = event.getAction();
switch (action ) {
case MotionEvent.ACTION_DOWN:
{
mPrevX = event.getRawX();
mPrevY = event.getRawY();
btnPrevX = tweatBtn.getX();
btnPrevY = tweatBtn.getY();
dragged = false; // global dragged variable
break;
}
case MotionEvent.ACTION_MOVE:
{
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth() + 80; // deprecated
int height = display.getHeight(); // deprecated
currX = event.getRawX();
currY = event.getRawY();
if(Math.abs(currX-mPrevX) > minTouchSlop || Math.abs(currY-mPrevY) > minTouchSlop)
dragged = true; // differntiate btw drag or click
if(tweatBtn.getY() > 80 && tweatBtn.getX() > 0 && tweatBtn.getX() < width)
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
else
{
if((btnPrevY + currY - mPrevY) > 70 && (btnPrevX + currX - mPrevX) > -10 && tweatBtn.getX() < (width - 10))
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return dragged;
}
I am trying to add pinch to zoom in my 3D view, and it doesn't work. Rotating is working, but not zooming.
I have also tried with ACTION_POINTER1_UP/DOWN, but that was a fail
Here's my code :
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getPointerCount() > 1)
{
int x1 = (int) event.getX(0);
int y1 = (int) event.getY(0);
int x2 = (int) event.getX(1);
int y2 = (int) event.getY(1);
d = Math.sqrt((x1-x2)^2+(y1-y2)^2);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
rotating = true;
break;
case MotionEvent.ACTION_UP:
rotating = true;
prevSwipeY = swipeY = 0; // for the Y axis
prevSwipeX = swipeX = 0; // for the X axis
break;
case MotionEvent.ACTION_MOVE:
float directionY = (prevSwipeY - event.getX()) * -1;
float directionX = (prevSwipeX - event.getY()) * -1;
swipeY = (int) (directionY * ROTATION_SPEED);
swipeX = (int) (directionX * ROTATION_SPEED);
if(event.getPointerCount() > 1)
{
int x1 = (int) event.getX(0);
int y1 = (int) event.getY(0);
int x2 = (int) event.getX(1);
int y2 = (int) event.getY(1);
d2 = Math.sqrt((x1-x2)^2+(y1-y2)^2);
r = d2/d;
}
break;
}
// Camera pivot point is different
prevSwipeY = (int) event.getX();
prevSwipeX = (int) event.getY();
return super.onTouchEvent(event);
}
#Override
public void updateScene() {
if (faceObject3D != null) { // If an object is loaded
if (swipeY != 0) // and we did swiped in the correct direction
faceObject3D.rotation().y += swipeY;
swipeY = 0; // Reset the pointer
if (swipeX != 0) // and we did swiped in the correct direction
faceObject3D.rotation().x += swipeX;
swipeX = 0; // Reset the pointer
if(r != 0) {faceObject3D.scale().x = faceObject3D.scale().y = faceObject3D.scale().z = (float) (r*2.0f);};
}
}
Do yo know what is missing ?