简体   繁体   English

让最后一根手指触摸屏幕

[英]Getting the last finger touching the screen

I need to do controls, and I am having problem with multi touch. 我需要进行控制,而多点触控存在问题。

The concept is easy: 这个概念很简单:

  • if the user touches the left (half of the screen) side the ship go to the left 如果用户触摸左侧(屏幕的一半),则船舶将向左侧移动
  • if the user touches the right (half of the screen) side the ship go to the right. 如果用户触摸右侧(屏幕的一半),则船舶将向右侧行驶。

The problems come when the user does the following: 用户执行以下操作时会出现问题:

  • Put finger on left side 将手指放在左侧
  • Without removing left finger, put finger on the right side 在不移开左手指的情况下,将手指放在右侧
  • remove left finger 移开左手指
  • Put again left finger (my code won't recognize it, there is the problem) 再次放左手指(我的代码无法识别它,有问题)

I want a code that only get the 'X' position of the last finger in the screen 我想要一个仅能获得屏幕上最后一根手指的“ X”位置的代码

My actual code: 我的实际代码:

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

I think by "the LAST finger in the screen" you mean the finger with the latest ACTION_DOWN/ACTION_POINTER_DOWN time. 我认为“屏幕上的最后一根手指”是指具有最新ACTION_DOWN / ACTION_POINTER_DOWN时间的手指。

Each time you get a DOWN/POINTER_DOWN event, get the ID of the action pointer with the method getActionIndex() and then getPointerID() , keep that in a field "lastActionDownId". 每次获得DOWN / POINTER_DOWN事件时,都使用方法getActionIndex()getPointerID()获取操作指针的ID,并将其保存在字段“ lastActionDownId”中。

Then, before you call touchNave() , get the index of the last down with findPointerIndex(lastActionDownId) . 然后,在调用touchNave() ,使用findPointerIndex(lastActionDownId)获取最后一个向下的索引。 Then use the getX(int index) with the result of that method call. 然后将getX(int index)与该方法调用的结果一起使用。

I made it by using a LinkedHashMap and using the last item of it code: 我通过使用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");
    } 
}

I never thought of a good solution for this, I ended up writing a rather lengthy class. 我从来没有想到过一个好的解决方案,我最终写了一个很长的课。 It seems odd but when you want to count the fingers correctly and account for lifting fingers so if you give the touch event numbers like #1 and #2, #3 etc, you need to know that finger #2 was lifted and thus fingers #1 and #3 are the valid events and the next finger touch is finger #2 back again. 看起来很奇怪,但是当您想正确地数指并考虑到手指举起时,因此,如果您提供诸如#1和#2,#3等的触摸事件编号,则需要知道手指#2被举起,因此手指# 1和#3是有效事件,下一次手指触摸是手指#2再次返回。

There's a lot of things with multiple fingers where doing it the naive way will suddenly teleport one finger location across the screen because you picked up the touches in different orders. 在很多情况下,用多根手指进行操作时,幼稚的方式会突然将一根手指的位置传送到屏幕上,因为您以不同的顺序拾取了触摸。 Especially if you want to store information about these touches. 特别是如果您想存储有关这些触摸的信息。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Android touchlistener中同时检测到触摸屏幕上的次要手指? - how to detect the secondary finger on touching the screen not at same time in android touchlistener? Android:当另一个手指已经触摸屏幕时,是否可以处理点击? - Android: Is it possible to handle a click while another finger is already touching the screen? 在 Android 上,当第一根手指从屏幕上松开时,如何判断第二根手指的位置,该手指没有移动但正在触摸屏幕 - On Android, how can I tell the location of a second finger that isn't moving but is touching the screen when the first finger releases from the screen 每当用户的手指不触摸屏幕时,我都想让游戏暂停 - I want to make my game pause whenever the users finger is not touching the screen 触摸屏幕即可移动矩形 - Move rectangle by touching the screen 手指在屏幕上滑动的灵敏度 - The sensitivity of the finger swipe on the screen 触摸屏时应用程序崩溃 - Application crashes upon touching screen LibGDX:实现触摸屏,而无需触摸屏幕 - LibGDX: Implement touch screen, without touching the screen 为什么在触摸Android屏幕时却什么也没做? - Why, when touching the Android screen it does nothing? 触摸屏时如何保留onTouchEvent? - How to retain onTouchEvent while touching screen?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM