15

I'm currently developing an air-hockey simulation for android. For the multiplayer mode I'm tracking two touch events on the screen, which works well as long as the touch points don't get to close. Normal Touch

When the two fingers get to close, android only recognizes one touch event, in the middle of both points.

Two events overlapping

To make it even worse, android sometimes messes up the IDs after the collision.

Wrong IDs assigned

I already thought about estimating the next touch points ans assigning IDs manually, does anybody know a better way, or knows about somebody who already fixed this problem programmatically?

NOTE: I'm testing on a Samsung Galaxy S 3

4

3 回答 3

6

不一定是对该问题的合乎逻辑的解决方案,但可能是该应用程序的解决方案:

如果我没有完全弄错的话,空气曲棍球比赛不应该让对手侵入对方的比赛场地。如果我们假设一个粗边框穿过屏幕中心(在纵向模式下),那么我将不会被允许在该边框之外做任何事情,因此在我的手指到达边界线后跟踪它是没有意义的。

如前所述,将跟踪的触摸事件封装到有效的物理位置中可能只会帮助您忽略无效点(假设物理位置不相交)。

您可能还必须跟踪触摸矢量的方向:如果矢量从屏幕中心向“您的末端”延伸,则可能是对手侵入手指或您自己返回的手指。在任何情况下,它们都不应该影响冰球(也许)。

于 2012-09-26T13:18:39.277 回答
2

这可能取决于您使用的设备,但我在华为 X5 中使用下面的代码并且它永远不会弄乱手指,即使它们相互接触或者我在屏幕上扭动它们。

private static PointF touchScreenStartPtArr[] = new PointF[10];
private static PointF touchScreenStopPtArr[] = new PointF[10];
private static PointF touchScreenCurrPtArr[] = new PointF[10];

OnTouchListener onTouchListenerMulti = new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        int action = event.getAction() & MotionEvent.ACTION_MASK;
        int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        int fingerId = event.getPointerId(pointerIndex);

        switch (action) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:
            touchScreenStartPtArr[fingerId].x = event.getX(pointerIndex);
            touchScreenStartPtArr[fingerId].y = event.getY(pointerIndex);
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_CANCEL:
            touchScreenStopPtArr[fingerId].x = event.getX(pointerIndex);
            touchScreenStopPtArr[fingerId].y  = event.getX(pointerIndex);
            break;
        case MotionEvent.ACTION_MOVE:
            int pointerCount = event.getPointerCount();
            for (int i = 0; i < pointerCount; i++) {
                touchScreenCurrPtArr[fingerId].x = event.getX(i);
                touchScreenCurrPtArr[fingerId].y = event.getY(i);
            }
            break;
        }
        return true;
    }
};  

请注意,我使用的是 fingerId 而不是 pointerId 来识别正确的手指,因为松开一根手指时指针 id 可能会发生变化。

希望对你有效。

于 2012-09-28T18:30:04.320 回答
2

这是我的看法。

触摸屏硬件为您提供了一个分辨率,低于该分辨率时两次触摸相同。这是你无法改变的。

现在的问题是,当两个触摸合并时该怎么办?(这是可以以编程方式测试的东西;例如,如果 2 touch pts -> 1 touch pt.​​ AND prev touch pt 1 足够接近 prev touch pt 2...)。在你的情况下,我会沿着合并的触摸手势移动两个圆盘,直到它们分开,然后返回单独的控制。

当然,我看到这有几个问题,比如拆分后哪个触摸控制哪个冰球?也许有人在合并过程中抬起了手指。

如果发生合并,您可能会让两个玩家都失去对冰球的控制。这可以模拟当你的手撞到对手的手腕时对手腕的冲击:)

我也喜欢@dbm 的想法。

希望这可以帮助。可能没有:)

于 2012-09-28T20:13:25.033 回答