How to Implement Swipe In Android Game Without View
Asked Answered
H

4

13

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?

Heterochromatin answered 3/11, 2014 at 16:15 Comment(1)
can you post the GameScreen class. and what errors are being thrown. Can you post the logcat stack trace? ...thus if your problem hasn't been resolvedClassified
W
2

If u have access to touch events then try this

    int len = touchEvents.size();
    Graphics g = game.getGraphics();

    for (int i = 0; i < len; i++) {

        TouchEvent event = touchEvents.get(i);


        if (event.type == TouchEvent.TOUCH_DOWN)
        {
            x1=event.x;
            y1=event.y;
        }
        if (event.type == TouchEvent.TOUCH_UP)
        {
            x2=event.x;
            y2=event.y;
            dx=(x2-x1);
            dy=(y2-y1);
            tu=1;
        }

        if((tu==1) && (Math.abs(dx)>Math.abs(dy)))
        {
                if(dx>0)
                {
                    if(!(robot.getSpeedX()<0))
                    {
                    robot.stop();
                    robot.moveRight();
                    }
                }
                else
                {
                    if(!(robot.getSpeedX()>0))
                    {
                    robot.stop();
                    robot.moveLeft();
                    }
                }
                tu=0;
        }
        if((tu==1) && (Math.abs(dx)<=Math.abs(dy)))
        {
                if(dy>0)
                {
                    if(!(robot.getSpeedY()<0))
                    {
                    robot.stop();
                    robot.moveDown();
                    }
                }
                else
                {
                    if(!(robot.getSpeedY()>0))
                    {
                    robot.stop();
                    robot.moveUp();
                    }
                }
                tu=0;
        }
Wardmote answered 16/11, 2014 at 11:59 Comment(0)
C
5

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.

Classified answered 13/11, 2014 at 22:15 Comment(0)
B
4

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.

Bancroft answered 13/11, 2014 at 11:9 Comment(0)
J
3

Put the super methods in your code, example:

public void onSwipeTop() {
    super.onSwipeTop();
    Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
}
Jugendstil answered 11/11, 2014 at 19:27 Comment(0)
W
2

If u have access to touch events then try this

    int len = touchEvents.size();
    Graphics g = game.getGraphics();

    for (int i = 0; i < len; i++) {

        TouchEvent event = touchEvents.get(i);


        if (event.type == TouchEvent.TOUCH_DOWN)
        {
            x1=event.x;
            y1=event.y;
        }
        if (event.type == TouchEvent.TOUCH_UP)
        {
            x2=event.x;
            y2=event.y;
            dx=(x2-x1);
            dy=(y2-y1);
            tu=1;
        }

        if((tu==1) && (Math.abs(dx)>Math.abs(dy)))
        {
                if(dx>0)
                {
                    if(!(robot.getSpeedX()<0))
                    {
                    robot.stop();
                    robot.moveRight();
                    }
                }
                else
                {
                    if(!(robot.getSpeedX()>0))
                    {
                    robot.stop();
                    robot.moveLeft();
                    }
                }
                tu=0;
        }
        if((tu==1) && (Math.abs(dx)<=Math.abs(dy)))
        {
                if(dy>0)
                {
                    if(!(robot.getSpeedY()<0))
                    {
                    robot.stop();
                    robot.moveDown();
                    }
                }
                else
                {
                    if(!(robot.getSpeedY()>0))
                    {
                    robot.stop();
                    robot.moveUp();
                    }
                }
                tu=0;
        }
Wardmote answered 16/11, 2014 at 11:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.