[英]Getting the last finger touching the screen
I need to do controls, and I am having problem with multi touch. 我需要进行控制,而多点触控存在问题。
The concept is easy: 这个概念很简单:
The problems come when the user does the following: 用户执行以下操作时会出现问题:
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.