我的游戏中有一个奇怪的问题。我正在使用2个操纵杆,一个用于射击/瞄准,一个用于移动我的角色。出于某种原因,我的多点触控方法一次只能记录一个动作。当我按下时,第二个指针被注册,但我的ACTION_MOVE
仅适用于第一个指针。这是奇怪的cus,这意味着它确实需要多于一个指针,但它不能同时移动多个指针。我已经在gamedev.stackexchange上问了这个问题并且它已经活动了大约一个星期,得到了几个答案,但没有任何让它100%工作的东西。我自己试了几个小时。
onTouch-method的代码:
//global variables
private int movePointerId = -1;
private int shootingPointerId = -1;
public void update(MotionEvent event) {
if (event == null && lastEvent == null) {
return;
} else if (event == null && lastEvent != null) {
event = lastEvent;
} else {
lastEvent = event;
}
// grab the pointer id
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
int actionIndex = event.getActionIndex();
int pid = action >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int x = (int) event.getX(pid);
int y = (int) event.getY(pid);
String actionString = null;
switch (actionCode)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
actionString = "DOWN";
try{
if(x > 0 && x < steeringxMesh + (joystick.get_joystickBg().getWidth() * 2)
&& y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
movingPoint.x = x;
movingPoint.y = y;
movePointerId = pid;
dragging = true;
//checks if Im pressing the joystick used for moving
}
else if(x > shootingxMesh - (joystick.get_joystickBg().getWidth()) && x < panel.getWidth()
&& y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
shootingPoint.x = x;
shootingPoint.y = y;
shootingPointerId = pid;
shooting=true;
//checks if Im pressing the joystick used for shooting
}
}catch(Exception e){
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
if( pid == movePointerId ){
movePointerId = -1;
dragging = false;
}
else if( pid == shootingPointerId ){
shootingPointerId = -1;
shooting=false;
}
actionString = "UP";
break;
case MotionEvent.ACTION_MOVE: // this is where my problem is
if( pid == movePointerId ) {
movingPoint.x = x;
movingPoint.y = y;
} else if( pid == shootingPointerId ) {
shootingPoint.x = x;
shootingPoint.y = y;
}
actionString = "MOVE";
break;
}
如果我打印actionString
和pid
,则表示在移动时,它只检查pid=0
,但是当我按下(ACTION_POINTER_DOWN
)时,我可以看到它确实注册另一个pid
,这真的让我感到困惑。
为了让它更清晰,当我按下第二个指针时,例如我的射击棒,它会占据我按下的位置,即使我同时移动另一个操纵杆,但它呆在那里,直到我放开另一个操纵杆。更确切地说,它确实注册了超过1次触摸,然后超过1 pid
。
如果您需要进一步的解释,请告诉我。
答案 0 :(得分:2)
我对您的代码进行了一些更改,我认为应该可以解决问题。至少它对我来说很好......
//global variables
private int movePointerId = -1;
private int shootingPointerId = -1;
public void update(MotionEvent event) {
if (event == null && lastEvent == null) {
return;
} else if (event == null && lastEvent != null) {
event = lastEvent;
} else {
lastEvent = event;
}
// grab the pointer id
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
int pid = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int fingerid = event.getPointerId(pid);
//int actionIndex = event.getActionIndex();
//int pid = action >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int x = (int) event.getX(pid);
int y = (int) event.getY(pid);
String actionString = null;
switch (actionCode)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
actionString = "DOWN";
try{
if(x > 0 && x < steeringxMesh + (joystick.get_joystickBg().getWidth() * 2)
&& y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
movingPoint.x = x;
movingPoint.y = y;
//movePointerId = pid;
movePointerId = fingerid;
dragging = true;
//checks if Im pressing the joystick used for moving
}
else if(x > shootingxMesh - (joystick.get_joystickBg().getWidth()) && x < panel.getWidth()
&& y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
shootingPoint.x = x;
shootingPoint.y = y;
//shootingPointerId = pid;
shootingPointerId = fingerid;
shooting=true;
//checks if Im pressing the joystick used for shooting
}
}catch(Exception e){
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
if( fingerid == movePointerId ){ //changed this line
movePointerId = -1;
dragging = false;
}
else if( fingerid == shootingPointerId ){ //changed this line
shootingPointerId = -1;
shooting=false;
}
actionString = "UP";
break;
case MotionEvent.ACTION_MOVE: // this is where my problem is
if( fingerid == movePointerId ) { //changed this line
movingPoint.x = x;
movingPoint.y = y;
} else if( fingerid == shootingPointerId ) { //changed this line
shootingPoint.x = x;
shootingPoint.y = y;
}
actionString = "MOVE";
break;
}
原因是在某些设备上,当您释放一根手指时,指针ID可能会发生变化。例如,第一个手指接收指针ID 1,然后按下接收指针ID 2的第二个手指,如果然后释放手指1,手指2的指针ID可能变为1.听起来有点令人困惑,但你应该避免上面这个手指的问题。
祝你好运。答案 1 :(得分:1)
指针有两种不同的属性可用于识别它们:
index :它的范围是0到1,小于 getPointerCount()返回的值。 仅在处理当前事件期间有效。
id :此属性唯一标识指针,并保证指针在整个生命周期内保持不变。
在您的代码中,您无法正确检索索引和 ID 信息。基本上,您使用索引来识别跨多个事件的指针,这是完全错误的,因为索引可能会有所不同,这正是您在应用中遇到的情况。简而言之,你应该使用id来识别指针。
正如我所提到的,他们检索索引和 id 的方法是错误的。检索这些属性的正确方法是:
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pid = event.getPointerId(index);
您可以在此处参阅更多信息:MotionEvent | Android Developers
答案 2 :(得分:0)
private int movePointerId = -1;
和private int shootingPointerId = -1;
,他们不应该有不同的价值观吗?我真的不知道但是一旦我遇到了问题,那么我就改变了价值观并且有效。