【问题标题】:How to make multitouch working in android?如何使多点触控在android中工作?
【发布时间】:2019-04-13 20:15:27
【问题描述】:

我正在用 android 创建 Pong 游戏,但我遇到了多点触控问题

为了移动我的两个玩家,我使用了 onTouchEvent 方法,两个玩家可以同时移动。有一个问题:如果屏幕上的最后一个手指不是第一个手指,我有一个异常,因为剩余手指的pointerId等于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)

如果有人可以帮助我解决我的问题,我将不胜感激。谢谢!

【问题讨论】:

    标签: java android multi-touch touch-event


    【解决方案1】:

    要跟踪来自多个指针的触摸事件,您必须使用 theMotionEvent.getActionIndex()theMotionEvent.getActionMasked() 方法来识别指针的索引以及此指针发生的触摸事件。

    这个指针索引可以随时间改变,例如如果一根手指从设备上抬起。指针的稳定版本是指针 id,可以通过 MotionEvent 对象中的 thegetPointerId(pointerIndex) 方法确定。

    @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() && posX <= joueur1.getX()+joueur1.getRayon()
                              && posY >= joueur1.getY()-joueur1.getRayon() && posY <= joueur1.getY()+joueur1.getRayon()
                              && posY < this.height/2-joueur1.getRayon()) {
      
                              joueur1.setX(posX);
                              joueur1.setY(posY);
                          }
                          //Déplacement du joueur 2
                          if (posX >= joueur2.getX()-joueur2.getRayon() && posX <= joueur2.getX()+joueur2.getRayon()
                                  && posY >= joueur2.getY()-joueur2.getRayon() && posY <= joueur2.getY()+joueur2.getRayon()
                                  && 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 循环来使多点触控工作吗?因为如果我不这样做,只能移动一名玩家。

      【讨论】:

        猜你喜欢
        • 2011-07-17
        • 2023-03-19
        • 2016-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-11
        • 1970-01-01
        • 2012-04-12
        相关资源
        最近更新 更多