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?
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.
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.
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.
Put the super methods in your code, example:
public void onSwipeTop() {
super.onSwipeTop();
Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With