I´m having the following problem in my game:
let´s say I have 5 screens on the lvl 3. Each screen has a class for itself. so i have 5 classes named lvl 3_1_0, 3_2_0 .... .... 3_5_0. I also have a gesture listener so when you swipe right it will go to the screen on the right. When playing normally it all works fine but if the user starts swiping right like crazy for example and he does it like a lot of times per second, the game crashes off course.
I thought about adding a "Thread.sleep" but I cant make it work when I put the Thread sleep the game crashes when loading the class. I think I´m putting it in the wrong place, or places.... the best would be if the gesture listener wait´s a second to be active. I also have a gesture filter class. I don´t know if I should put the thread.sleep in the gesture filter class or in the gesture listener that is in every class.
here is the code of the on create and the gesture listener...
public class lvl3_5_0 extends Activity implements View.OnTouchListener , SimpleGestureListener {
public static final String PREFS_NAME = "MyPrefsFile";
static SharedPreferences settings;
SharedPreferences.Editor editor;
private SimpleGestureFilter detector;
static final int MIN_DISTANCE = 100;
@Override
public void onCreate(Bundle savedInstanceState) {
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
detector = new SimpleGestureFilter(this,this);
super.onCreate(savedInstanceState);
setContentView(R.layout.lvl3_5_0);
ImageView iv = (ImageView) findViewById (R.id.image);
if (iv != null) {
iv.setOnTouchListener (this);
}
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
//-----------------------------
// Gesture detection
@Override
public boolean dispatchTouchEvent(MotionEvent me){
this.detector.onTouchEvent(me);
return super.dispatchTouchEvent(me);
}
@Override
public void onSwipe(int direction) {
switch (direction) {
case SimpleGestureFilter.SWIPE_RIGHT : {
{ Intent game = new Intent(lvl3_5_0.this, lvl3_4_0.class);
game.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); game.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mHandler.removeCallbacks(dismissPopup);
this.finish(); startActivity(game);
}break;}
case SimpleGestureFilter.SWIPE_LEFT :{
{ Intent game = new Intent(lvl3_5_0.this, lvl3_1_0.class);
game.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); game.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mHandler.removeCallbacks(dismissPopup);
this.finish(); startActivity(game);
}break;}
case SimpleGestureFilter.SWIPE_DOWN : {
break;}
case SimpleGestureFilter.SWIPE_UP :{
openOptionsMenu(); ;
}
break;
}
}
And here is my Gesture Filter Class
public class SimpleGestureFilter extends SimpleOnGestureListener{
public final static int SWIPE_UP = 1;
public final static int SWIPE_DOWN = 2;
public final static int SWIPE_LEFT = 3;
public final static int SWIPE_RIGHT = 4;
public final static int MODE_TRANSPARENT = 0;
public final static int MODE_SOLID = 1;
public final static int MODE_DYNAMIC = 2;
private final static int ACTION_FAKE = -13; //just an unlikely number
private int swipe_Min_Distance = 65;
private int swipe_Max_Distance = 1111100;
private int swipe_Min_Velocity = 60;
private int mode = MODE_DYNAMIC;
private boolean running = true;
private boolean tapIndicator = false;
private Activity context;
private GestureDetector detector;
private SimpleGestureListener listener;
public SimpleGestureFilter(Activity context,SimpleGestureListener sgl) {
this.context = context;
this.detector = new GestureDetector(context, this);
this.listener = sgl;
}
public void onTouchEvent(MotionEvent event){
if(!this.running)
return;
boolean result = this.detector.onTouchEvent(event);
if(this.mode == MODE_SOLID)
event.setAction(MotionEvent.ACTION_CANCEL);
else if (this.mode == MODE_DYNAMIC) {
if(event.getAction() == ACTION_FAKE)
event.setAction(MotionEvent.ACTION_UP);
else if (result)
event.setAction(MotionEvent.ACTION_CANCEL);
else if(this.tapIndicator){
event.setAction(MotionEvent.ACTION_DOWN);
this.tapIndicator = false;
}
}
//else just do nothing, it's Transparent
}
public void setMode(int m){
this.mode = m;
}
public int getMode(){
return this.mode;
}
public void setEnabled(boolean status){
this.running = status;
}
public void setSwipeMaxDistance(int distance){
this.swipe_Max_Distance = distance;
}
public void setSwipeMinDistance(int distance){
this.swipe_Min_Distance = distance;
}
public void setSwipeMinVelocity(int distance){
this.swipe_Min_Velocity = distance;
}
public int getSwipeMaxDistance(){
return this.swipe_Max_Distance;
}
public int getSwipeMinDistance(){
return this.swipe_Min_Distance;
}
public int getSwipeMinVelocity(){
return this.swipe_Min_Velocity;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
final float xDistance = Math.abs(e1.getX() - e2.getX());
final float yDistance = Math.abs(e1.getY() - e2.getY());
if(xDistance > this.swipe_Max_Distance || yDistance > this.swipe_Max_Distance)
return false;
velocityX = Math.abs(velocityX);
velocityY = Math.abs(velocityY);
boolean result = false;
if(velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance){
if(e1.getX() > e2.getX()) // right to left
this.listener.onSwipe(SWIPE_LEFT);
else
this.listener.onSwipe(SWIPE_RIGHT);
result = true;
}
else if(velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance){
if(e1.getY() > e2.getY()) // bottom to up
this.listener.onSwipe(SWIPE_UP);
else
this.listener.onSwipe(SWIPE_DOWN);
result = true;
}
return result;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
this.tapIndicator = true;
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent arg0) {
if(this.mode == MODE_DYNAMIC){ // we owe an ACTION_UP, so we fake an
arg0.setAction(ACTION_FAKE); //action which will be converted to an ACTION_UP later.
this.context.dispatchTouchEvent(arg0);
}
return false;
}
static interface SimpleGestureListener{
void onSwipe(int direction);
}
}
So the questions would be: Where should I put the "Thread.sleep(1000);" surrounded by try/catch? ( if that´s what I have to use )
I tried a lot and I´m stuck
----------------------------Solved--------------------------------------
here is the code fixed
public class lvl3_3_0 extends Activity implements View.OnTouchListener , SimpleGestureListener {
boolean finished = false; // This was added ( no need to explain XD )
private SimpleGestureFilter detector;
static final int MIN_DISTANCE = 100;
// Handler and runnable reference
private PopupWindow popupWindow;
private Handler mHandler = new Handler();
private Runnable dismissPopup = new Runnable() {
public void run() {
if (popupWindow.isShowing())
popupWindow.dismiss();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {{
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
detector = new SimpleGestureFilter(this,this);
settings = getSharedPreferences(PREFS_NAME, 0);
editor = settings.edit();
editor.putString("currentscreen", "com.appsimple.roomdroid.lvl3_3_0");
editor.commit();
super.onCreate(savedInstanceState);
setContentView(R.layout.lvl3_3_0);
ImageView iv = (ImageView) findViewById (R.id.image);
if (iv != null) {
iv.setOnTouchListener (this);
}
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
finished = true; // This will make true the boolean after finishing the loading of the activity
}
//-----------------------------
// Gesture detection
@Override
public boolean dispatchTouchEvent(MotionEvent me){
if (!finished){} // This was added to make the gesturelistener not to listen if the activity has not finished loading.
else {
this.detector.onTouchEvent(me);
return super.dispatchTouchEvent(me); }
return false;
}
@Override
public void onSwipe(int direction) {
if (!finished){}
else {
switch (direction) {
case SimpleGestureFilter.SWIPE_RIGHT : {
finished = false; // this wass added after doing the swipe to avoid the gesture listener to have a que of events.
{ Intent game = new Intent(lvl3_3_0.this, lvl3_2_0.class);
game.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); game.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mHandler.removeCallbacks(dismissPopup);
this.finish(); startActivity(game);
}break;}
case SimpleGestureFilter.SWIPE_LEFT :{
{ finished = false; Intent game = new Intent(lvl3_3_0.this, lvl3_4_0.class);
game.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); game.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mHandler.removeCallbacks(dismissPopup);
this.finish(); startActivity(game);
}break;}
case SimpleGestureFilter.SWIPE_DOWN : {
break;}
case SimpleGestureFilter.SWIPE_UP :{
openOptionsMenu(); ;
}
break;
} }}
Hope this helps ! Thaks AndroidPenguin for the help :)
the other solution i was thinking about was a bit laggi and not this good was making a Runnable in the gesture filter class to work as a timer every time the timer got to for example 1 sec it would return the "isoktodotheswipe" boolean and every time a wipe was made the "isoktodotheswipe" boolean would become false...