Как заставить мультитач работать в Android?

#java #android #multi-touch #touch-event

#java #Android #мультитач #касание-событие

Вопрос:

Я создаю игру в понг на Android, и у меня проблема с мультитач

Чтобы переместить двух моих игроков, я использую метод onTouchEvent, и оба игрока могут быть перемещены одновременно. Есть одна проблема: если последний палец вниз на экране не является первым вверх, у меня возникает исключение, потому что идентификатор указателя оставшегося пальца равен pointerCount, и моя игра завершается. И я должен использовать метод onTouchEvent, чтобы получить координаты x и y всех пальцев на экране.

  @SuppressLint("ClickableViewAccessibility")
    public boolean onTouchEvent(MotionEvent event) {
        final int actionPerformed = event.getAction();
        switch(actionPerformed) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                int pointerCount = event.getPointerCount();
                for(int i=0; i<pointerCount; i  ) {
                    int x = (int) event.getX(event.getPointerId(i));
                    int y = (int) event.getY(event.getPointerId(i));
                    if(y<this.height/2-joueur1.getRayon()-1) { joueur1.setX(x); joueur1.setY(y); }
                    else if(y>this.height/2 joueur2.getRayon() 1){ joueur2.setX(x); joueur2.setY(y); }
                }
                break;
            case MotionEvent.ACTION_UP:
        }
        return true;
    }
//This is the message shown when I'm releasing a finger which is not the last one down

E/MotionEvent-JNI: An exception occurred: pointerCount 1, pointerIndex 1.
E/InputEventReceiver: Exception dispatching input event.
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.pong, PID: 29258
    java.lang.IllegalArgumentException: pointerIndex out of range
        at android.view.MotionEvent.nativeGetAxisValue(Native Method)

  

Если кто-нибудь может помочь мне решить мою проблему, я был бы благодарен. Спасибо!

Ответ №1:

Чтобы отслеживать события касания из нескольких указателей, вы должны использовать theMotionEvent.getActionIndex() theMotionEvent.getActionMasked() методы и для определения индекса указателя и события касания, которое произошло для этого указателя.

Этот индекс указателя может меняться со временем, например, если убрать один палец с устройства. Стабильная версия указателя — это идентификатор указателя, который можно определить с thegetPointerId(pointerIndex) помощью метода из MotionEvent объекта.

 @Override
public boolean onTouchEvent(MotionEvent event)  
 { 
 // get pointer index from the event object int
  pointerIndex = event.getActionIndex();
// get pointer ID 
 int pointerId = event.getPointerId(pointerIndex);
// get masked (not specific to a pointer) action
 int maskedAction = event.getActionMasked();
 switch (maskedAction) 
       { 
        case MotionEvent.ACTION_DOWN: 
          case MotionEvent.ACTION_POINTER_DOWN:
             { 
                // TODO use data break;
             }
          case MotionEvent.ACTION_MOVE:
           {
           // a pointer was moved 
          // TODO use data break;
            } 
           case MotionEvent.ACTION_UP:
           case MotionEvent.ACTION_POINTER_UP:       
           case MotionEvent.ACTION_CANCEL:
           { 
            // TODO use data break; 
           }
      } 
 invalidate(); 
 return true;
 }
  

Ответ №2:

Спасибо за ваш ответ, но у меня все еще есть эта проблема с использованием getActionMasked() и getActionIndex()… Это мой новый код :

 @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //Detection du nombre de doigts sur l'écran et deplacement des joueurs en fonction de la position des doigts
        int pointerCount = event.getPointerCount();
        for(int i=0; i<pointerCount; i  ) {
            int pointerIndex = event.getActionIndex();
            int pointerId    = event.getPointerId(pointerIndex);
            int maskedAction = event.getActionMasked();

            switch(maskedAction) {
                case MotionEvent.ACTION_DOWN:
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:

                    break;

                case MotionEvent.ACTION_MOVE:
                    int x = (int) event.getX(pointerId);
                    int y = (int) event.getY(pointerId);

                    this.posX = x; this.posY = y;

                    //Déplacement du joueur 1
                    if (posX >= joueur1.getX()-joueur1.getRayon() amp;amp; posX <= joueur1.getX() joueur1.getRayon()
                        amp;amp; posY >= joueur1.getY()-joueur1.getRayon() amp;amp; posY <= joueur1.getY() joueur1.getRayon()
                        amp;amp; posY < this.height/2-joueur1.getRayon()) {

                        joueur1.setX(posX);
                        joueur1.setY(posY);
                    }
                    //Déplacement du joueur 2
                    if (posX >= joueur2.getX()-joueur2.getRayon() amp;amp; posX <= joueur2.getX() joueur2.getRayon()
                            amp;amp; posY >= joueur2.getY()-joueur2.getRayon() amp;amp; posY <= joueur2.getY() joueur2.getRayon()
                            amp;amp; posY > this.height/2 joueur2.getRayon()) {

                        joueur2.setX(posX);
                        joueur2.setY(posY);
                    }
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    break;
            }
        }
        return true;
  

Нужно ли мне использовать цикл for, чтобы заставить мультитач работать? Потому что только один проигрыватель может быть перемещен, если я этого не сделаю.