开发者

Android: detect if area is being pressed with any of the fingers

开发者 https://www.devze.com 2023-03-22 20:39 出处:网络
I\'ve got a SurfaceView, where I\'m painting a circle. I know the position and the radius of the circle.

I've got a SurfaceView, where I'm painting a circle. I know the position and the radius of the circle.

I need to know whether the circle is being pressed by the user. The user may being tapping the screen with one or two fingers. If any of the fingers is over the area of the circle, it has to be pressed.

When the user raises the finger from the screen, and there are no longer fingers over the circle, the circle has to stop being pressed.

I've got no problems when the user has only one finger on the screen, but I cannot resolve the problem when he's using two fingers.

The problem I have is that when I receive an ACTION_UP or ACTION_POINTER_UP action, I don't know which pointer is no longer on screen, so I don't have to look if their coordinates are over the circle.

I've done several tries without success, last one is:

protected boolean checkPressed(MotionEvent event) {

    ColourTouchWorld w = (ColourTouchWorld)gameWorld;

    int actionMasked = event.getActionMasked();

    for (int i = 0; i < event.getPointerCount(); i++) {
        if (i == 0 && (actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_POINTER_UP)) {
            // the pointer with index 0 is no longer on screen, 开发者_StackOverflow中文版
            // so the circle is not pressed by this pointer, even if
            // it's coordinates are over the area of the circle

            continue;
        }

        if (isPointInCicle(event.getX(i)), event.getY(i))) {
           return true;
        }
    }

    return false;
}

Any ideas? Thank you.


In the method written in the question I was assuming that the action received referred to the pointer with index 0. I was wrong, but I needed to use ACTION_POINTER_INDEX_MASK

The correct implementation of the method is:

protected boolean checkPressed(MotionEvent event) {

ColourTouchWorld w = (ColourTouchWorld)gameWorld;

int actionMasked = event.getActionMasked();
int pointerIndex = ((event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT);

for (int i = 0; i < event.getPointerCount(); i++) {
    if (i == pointerIndex  && (actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_POINTER_UP)) {
        // the pointer with index 0 is no longer on screen, 
        // so the circle is not pressed by this pointer, even if
        // it's coordinates are over the area of the circle

        continue;
    }

    if (isPointInCicle(event.getX(i)), event.getY(i))) {
       return true;
    }
}

return false;
}


You need to use the ACTION_POINTER_INDEX_MASK constant. I have never implemented this so I don't know how the code will look. But I think you're going to need to use this.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号