【问题标题】:Getting the last finger touching the screen让最后一根手指触摸屏幕
【发布时间】:2015-03-02 16:55:27
【问题描述】:

我需要进行控制,但我遇到了多点触控问题。

这个概念很简单:

  • 如果用户触摸左侧(屏幕的一半),船会向左移动
  • 如果用户触摸右侧(屏幕的一半),船会向右移动。

当用户执行以下操作时会出现问题:

  • 将手指放在左侧
  • 不移开左手指,将手指放在右侧
  • 移开左手指
  • 再放左手指(我的代码无法识别,有问题)

我想要一个仅获取屏幕中最后一个手指的“X”位置的代码

我的实际代码:

    @Override
public boolean onTouchEvent(MotionEvent event)
{
    int index = MotionEventCompat.getPointerCount(event) - 1;

    float x = (int) MotionEventCompat.getX(event, index);       
    @SuppressWarnings("deprecation")
    int ancho = AEngine.display.getWidth();

    switch (MotionEventCompat.getActionMasked(event))
    {
        case MotionEvent.ACTION_DOWN:
            if (gameView != null)
                gameView.touchNave(x, ancho);
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            if (gameView != null)
                gameView.touchNave(x, ancho);
            break;
        case MotionEvent.ACTION_MOVE:
            if (gameView != null)
                gameView.touchNave(x, ancho);
            break;

        case MotionEvent.ACTION_UP:
            Nave.estado = AEngine.NAVE_STAY;
            break;
        case MotionEvent.ACTION_POINTER_UP:
            Nave.estado = AEngine.NAVE_STAY;
            break;
    }


    return false;
}

【问题讨论】:

    标签: java android multi-touch motionevent


    【解决方案1】:

    我认为“屏幕上的最后一个手指”是指具有最新 ACTION_DOWN/ACTION_POINTER_DOWN 时间的手指。

    每次收到 DOWN/POINTER_DOWN 事件时,使用方法 getActionIndex()getPointerID() 获取操作指针的 ID,并将其保存在字段“lastActionDownId”中。

    然后,在调用touchNave() 之前,使用findPointerIndex(lastActionDownId) 获取最后一个向下的索引。然后将getX(int index) 与该方法调用的结果一起使用。

    【讨论】:

    • 感谢您的回复,我回家后会尝试,如果有效,我会将其标记为正确答案
    【解决方案2】:

    我通过使用 LinkedHashMap 并使用它的最后一项代码实现了它:

    LinkedHashMap<Integer, Float> al = new LinkedHashMap<Integer, Float>();
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        int index = MotionEventCompat.getActionIndex(event);
        int id = event.getPointerId(index);
    
        float x = (int) MotionEventCompat.getX(event, index);
    
    
        @SuppressWarnings("deprecation")
        int ancho = AEngine.display.getWidth();
    
        switch (MotionEventCompat.getActionMasked(event))
        {
            case MotionEvent.ACTION_DOWN:
                anadir(id,x);               
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                anadir(id,x);
                break;
    
            case MotionEvent.ACTION_UP:
                al.remove(id);
                break;
            case MotionEvent.ACTION_POINTER_UP:         
                al.remove(id);
                break;
        }
    
        if(al.size() > 0)
        {
            if (gameView != null)
                gameView.touchNave(getX(al), ancho);
        }
        else 
        {
            Nave.estado = AEngine.NAVE_STAY;
        }
    
        return false;
    }
    public float getX(LinkedHashMap<Integer,Float> map) {
        Iterator<Map.Entry<Integer,Float>> iterator = map.entrySet().iterator();
        float x = 0;
        while (iterator.hasNext()) {
            x = iterator.next().getValue();
        }
        return x;
    }
    
    public void anadir(int id,float x)
    {
        if (al.size() > 0 || !al.containsKey(id))
        {
            al.put(id, x);  
            Log.e("WTF",Integer.toString(id)+ "añadido");
        } 
    }
    

    【讨论】:

      【解决方案3】:

      我从来没有想过一个好的解决方案,我最终写了一个相当长的课程。这看起来很奇怪,但是当您想正确计算手指并考虑抬起手指时,因此如果您给出触摸事件编号(如 #1 和 #2、#3 等),您需要知道手指 #2 已抬起,因此手指 # 1 和 #3 是有效事件,下一个手指触摸是手指 #2 再次返回。

      有很多事情需要多根手指,因为你以不同的顺序拾取触摸,所以幼稚的方式会突然将一个手指的位置传送到屏幕上。特别是如果您想存储有关这些触摸的信息。

      public class TouchTrack {
      
          private static final int INVALID = -1;
          private static final int POINTERMAX = 5;
      
          HashMap<Integer, TouchData> touches = new HashMap<>();
          ArrayList<TouchData> fingers = new ArrayList<>(POINTERMAX);
      
      
          public void setEventPointers(MotionEvent event) {
              int count = event.getPointerCount();
              count = Math.min(count, POINTERMAX);
              for (int i = 0; i < count; i++) {
                  int id = event.getPointerId(i);
                  TouchData td = touches.get(id);
                  if (td == null) {
                      //Log.e("Touch", "Log does not have records for ID: " + id);
                      return;
                  }
                  td.x = event.getX(i);
                  td.y = event.getY(i);
              }
          }
      
          public void setLostPointer(MotionEvent event) {
              int index = event.getActionIndex();
              if (index >= POINTERMAX) return;
              int id = event.getPointerId(index);
              TouchData finger = touches.get(id);
              finger.id = INVALID;
          }
      
          public void setNewPointer(MotionEvent event) {
              int index = event.getActionIndex();
              if (index >= POINTERMAX) return;
              int id = event.getPointerId(index);
      
              for (int i = 0; i < POINTERMAX; i++) {
                  TouchData finger = fingers.get(i);
                  if (finger.id == INVALID) {
                      finger.id = id;
                      finger.x = event.getX();
                      finger.y = event.getY();
                      touches.put(id, finger);
                      break;
                  }
              }
          }
      
          public double lastEventX(int requestIndex) {
              if ((requestIndex >= 0) && (requestIndex < POINTERMAX)) {
                  TouchData td = fingers.get(requestIndex);
                  if (td == null) return 0;
                  return td.x;
              }
              return 0;
          }
      
          public double lastEventY(int requestIndex) {
              if ((requestIndex >= 0) && (requestIndex < POINTERMAX)) {
                  TouchData td = fingers.get(requestIndex);
                  if (td == null) return 0;
                  return td.y;
              }
              return 0;
          }
      
          public boolean isPointerActive(int requestIndex) {
              if ((requestIndex >= 0) && (requestIndex < POINTERMAX)) {
                  TouchData td = fingers.get(requestIndex);
                  if (td == null) return false;
                  return td.id != INVALID;
              }
              return false;
          }
      
          public void start(float x, float y) {
              touches.clear();
              fingers.clear();
              for (int i = 0; i < POINTERMAX; i++) {
                  fingers.add(new TouchData(x, y));
              }
          }
      
          public void stop() {
              touches.clear();
              fingers.clear();
          }
      
          public class TouchData {
              static final int INVALID = -1;
              public int id = INVALID;
              public double x = 0;
              public double y = 0;
      
              public TouchData(double x, double y) {
                  this.x = x;
                  this.y = y;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-31
        相关资源
        最近更新 更多