NCode
NCode

Reputation: 2808

Android multi-touch interference

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

Upvotes: 15

Views: 4603

Answers (3)

heycosmo
heycosmo

Reputation: 1398

Here's the way I see it.

The touchscreen hardware gives you a resolution below which two touches are the same as one. This is something you cannot change.

Now the question is, what to do when two touches merge? (This is something that can be tested for programmatically one would think; e.g. if 2 touch pts -> 1 touch pt. AND prev touch pt 1 is close enough to prev touch pt 2...). In your case, I would move both pucks along the merged touch gesture until they separate, then return individual control.

Of course, I see several problems with this, like which touch controls which puck after the split? Maybe one person lifted their finger during the merge.

You could have both players lose control of their puck if a merge occurs. This could simulate the shock to the wrist as your hand bashes into your opponent's :)

I also like @dbm idea.

Hope this helps. Probably didn't :)

Upvotes: 2

Luis
Luis

Reputation: 12058

It may depend on the device you are using, but I'm using the code below in a Huawei X5 and It never mess up fingers, even if they touch each other or it I twist them over the screen.

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

Note that I'm using fingerId and not pointerId to identify the correct finger, as pointer id may change when one finger is released.

Hope it works for you.

Upvotes: 2

dbm
dbm

Reputation: 10485

Not necessarily a logical fix to the issue, nevertheless a possible solution to the application:

If I'm not completely mistaken, air-hockey games shouldn't allow opponents to intrude on each others game field. If we assume a thick border cross the center of the screen (in portrait mode), then I wouldn't be allowed to do anything beyond that border, hence there is no point in tracking my finger after it reaches the border line.

Encapsulating your tracked touch events into valid physical locations as described might just help you in ignoring invalid points (given that the physical locations doesn't intersect, that is).

You might also have to keep track of direction of the touch vector: if the vector is stretching from the center of the screen towards "your end" it might be the opponents intruding finger or your own returning finger. In neither case should they affect the hockey puck (perhaps).

Upvotes: 6

Related Questions