经过大量的修修补补,我想我终于为我的安卓游戏想出了一个好的多点触控处理系统。它利用了 Robert Greene 的 Input Pipeline,经过修改后可与多点触控一起使用。现在,代码有一个简单的系统,可以记录哪个指针 ID 当前正在执行哪个动作(现在只是射击和移动)。每个指针的状态都保存在一个Pointer类中,它只是简单的封装了它是否向下,以及它的坐标。ID 充当指针数组索引。
这似乎在实践中应该运作良好,但在游戏中它的行为非常不稳定。在 LogCat 中记录指针动作时,Android 经常会在指针保持向下时发送“UP”动作,或者就在指针的一些“MOVE”动作之前发送一个“UP”动作。因为我的代码认为指针是向上的,所以游戏没有响应它。
这也发生在按下按钮(如拍摄按钮)时。当指针落在该区域(现在只是左下区域)时,Android 将发送多个“向上”和“向下”动作,即使指针始终保持向下。我之前有一个单点触控移动系统,这些问题都没有发生。
这只是我对事件的反应方式的问题吗?我应该分别处理 POINTER_DOWN 和 DOWN 吗?或者我应该在“UP”操作之后检测哪些指针正在移动,以查看哪些指针确实下降了,尽管 Android 说了什么?
这是我线程中的当前代码,它接收来自 Android 的输入事件。因为它是一个管道系统,所以我将事件封装在 InputObject 中,这有点类似于 Robert Greene 的。也许一双新的眼睛可以帮助我分辨出什么问题?谢谢你的帮助!
private int inx, iny;
private int shootID;
public boolean shooting = false;
private int moveID;
public boolean moveDown = false;
private static final int MAX_POINTERS = 10;
private Pointer[] pointers = new Pointer[MAX_POINTERS];
public void inputTouch(InputObject in) {
switch(in.action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
pointers[in.pID].press(in.pX[in.actionIndex], in.pY[in.actionIndex]);
//Log.i("D", "DOWN");
break;
case MotionEvent.ACTION_MOVE:
for(int p = 0; p < in.pointCount; p++) {
int id = in.pointerIDs[p];
pointers[id].setCoord(in.pX[id], in.pY[id]);
}
//Log.i("D", "MOVE");
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
pointers[in.pID].release();
if(shootID == in.pID) {
shooting = false;
}
if(moveID == in.pID) {
moveDown = false;
}
//Log.i("D", "UP");
break;
case MotionEvent.ACTION_CANCEL:
default:
break;
}
for(int ap = 0; ap < MAX_POINTERS; ap++) {
if(pointers[ap].down) {
if(pointers[ap].x < world.cam.pixelWidth / 4 &&
pointers[ap].y > world.cam.pixelHeight - (world.cam.pixelHeight / 4)) {
shootID = ap;
shooting = true;
} else {
inx = pointers[ap].x;
iny = pointers[ap].y;
moveID = ap;
moveDown = true;
}
}
}
StringBuilder sb = new StringBuilder();
for(int j = 0; j < 3; j++) {
sb.append("ID " + (j+1) + ": " + pointers[j].down + "[" + pointers[j].x + ", " + pointers[j].y + "]" + " | ");
}
//Log.i("D", sb.toString());
}