Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Implement Swipe In Android Game Without View

I'm trying to make a Snake game on Android in which the snake moves with swipe gestures.

I've tried a lot of ways to get this done but none of them seem to work for me. I haven't implemented a view - will that be a problem?

This is a sample I tried implementing based on a previous StackOverflow question - Android: How to handle right to left swipe gestures.

I created OnSwipeTouchListener.java as instructed. I ran into a bit of a problem with the usage, however.

In GameScreen.java (which is where all the touch events go), I added this as a sample -

onSwipeTouchListener = new OnSwipeTouchListener() {
public void onSwipeTop() {
    Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
  }
public void onSwipeRight() {
    Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show();
  }
public void onSwipeLeft() {
    Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
  }
public void onSwipeBottom() {
    Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show();
  }
};

imageView.setOnTouchListener(onSwipeTouchListener);

This causes a bunch of errors to show up (mainly involving imageView), and none of them could be resolved.

Would anybody happen to have an alternative implementation of swipe specific to my case?

like image 988
Caife Avatar asked Nov 03 '14 16:11

Caife


People also ask

What is fling gesture in Android?

Fling-based animation uses a friction force that is proportional to an object's velocity. Use it to animate a property of an object and to end the animation gradually. It has an initial momentum, which is mostly received from the gesture velocity, and gradually slows down.


3 Answers

You can do this in two ways:

Option 1:

Within your game's underlying activity class:

class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            try {
                float slope = (e1.getY() - e2.getY()) / (e1.getX() - e2.getX());
                float angle = (float) Math.atan(slope);
                float angleInDegree = (float) Math.toDegrees(angle);
                // left to right
                if (e1.getX() - e2.getX() > 20 && Math.abs(velocityX) > 20) {
                    if ((angleInDegree < 45 && angleInDegree > -45)) {                      
          //code for left to right swipe should go here
        }
                    // right to left fling
                } else if (e2.getX() - e1.getX() > 20
                        && Math.abs(velocityX) > 20) {
                    if ((angleInDegree < 45 && angleInDegree > -45)) {
      //code for right to left swipe should go here

                    }
                }
                return true;
            } catch (Exception e) {
                // nothing
            }
            return false;
        }
    }

You can then register any view to receive/listen for the gestures:

 final GestureDetector  gestureDetector = new GestureDetector(new MyGestureDetector());
                gameView.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });
         //the parent layout   
                findViewById(R.id.parent_layout).setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });
         //an image view
        findViewById(R.id.image_view).setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });

Option 2:

If the GameScreen class directly has access to touch events, you can read them and implement a logic for swipe actions. The code for that is similar to Mostafa Gazar's answer.

like image 163
Nana Ghartey Avatar answered Oct 24 '22 05:10

Nana Ghartey


You should post your GameScreen as Nana Ghartey

Assuming you have access to touch data you can do something like the following

private static final int DEFAULT_THRESHOLD = 36;// Better to be something in dps.

... = new View.OnTouchListener() {

    int initialX = 0;
    int initialY = 0;
    final float slop = ViewConfiguration.get(context).getScaledTouchSlop();

    public boolean onTouch(final View view, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            initialX = (int) event.getX();
            initialY = (int) event.getY();
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            int currentX = (int) event.getX();
            int currentY = (int) event.getY();
            int offsetX = currentX - initialX;
            int offsetY = currentY - initialY;
            if (Math.abs(offsetX) > slop) {
                if (offsetX > DEFAULT_THRESHOLD) {
                    // TODO :: Do Right to Left action!
                } else if (offsetX < -DEFAULT_THRESHOLD) {
                    // TODO :: Do Left to Right action!
                }
            }
            if (Math.abs(offsetY) > slop) {
                if (offsetY > DEFAULT_THRESHOLD) {
                    // TODO :: Do Bottom to Top action!
                } else if (offsetY < -DEFAULT_THRESHOLD) {
                    // TODO :: Do Top to Bottom action!
                }
            }
        } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
            // Do nothing!
        }
};

Good thing about this implementation is that user will not have to take her hand off the screen while controlling snake direction.

like image 22
Mostafa Gazar Avatar answered Oct 24 '22 04:10

Mostafa Gazar


Put the super methods in your code, example:

public void onSwipeTop() {
    super.onSwipeTop();
    Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
}
like image 3
Lukos Avatar answered Oct 24 '22 03:10

Lukos