13

Sto provando a creare un gioco Snake su Android in cui il serpente si muove con gesti di scorrimento.Come implementare lo scorrimento nel gioco Android senza vista

Ho provato un sacco di modi per ottenere questo risultato, ma nessuno di loro sembra funzionare per me. Non ho implementato una vista - sarà un problema?

Questo è un esempio che ho provato ad implementare in base a una precedente domanda StackOverflow - Android: How to handle right to left swipe gestures.

Ho creato OnSwipeTouchListener.java come indicato. Ho incontrato un po 'di problemi con l'utilizzo, tuttavia.

In GameScreen.java (che è dove tutti gli eventi touch vanno), ho aggiunto questo come un campione -

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); 

Questo fa sì che un mucchio di errori di presentarsi (coinvolgendo principalmente ImageView), e nessuno di loro potrebbero essere risolti.

Qualcuno potrebbe avere un'implementazione alternativa di scorrimento specifico per il mio caso?

+0

potete inserire la classe GameScreen. e quali errori vengono lanciati. Puoi pubblicare la traccia dello stack logcat? ... quindi se il tuo problema non è stato risolto –

risposta

2

Se u hanno accesso a toccare gli eventi quindi provare questo

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; 
     } 
+0

Questo sembra risolvere il problema. Grazie :) – Caife

3

Mettere i metodi di super nel codice, ad esempio:

4

Si dovrebbe pubblicare il tuo GameScreen come Nana Ghartey

Supponendo di avere accesso a toccare i dati si può fare qualcosa di simile a

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! 
     } 
}; 

La cosa buona di questa implementazione è che l'utente non dovrà togliere la mano dallo schermo Controlla la direzione del serpente.

5

È possibile farlo in due modi:

Opzione 1:

All'interno classe di attività sottostante del vostro gioco:

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; 
     } 
    } 

È possibile quindi registrare qualsiasi vista a ricevere/ascolta i gesti:

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; 
        } 
       }); 

Opzione 2:

Se la classe GameScreen ha direttamente accesso a toccare eventi, è possibile leggerli e implementare una logica per le azioni magnetiche. Il codice per questo è simile alla risposta di Mostafa Gazar.