users have to click certain points on a image tells me that instead of imposing invisible / transparent buttons on the image , each of which has its own event processing, you selected any clicks on the image sent to one place and is going to decide which clicks go for what purpose .
(a)
(b)
(from)
This means that if your image looked like (a) that you adjusted your points (pixel locations), for example (b):
This, for obvious reasons, causes you problems, because itโs very difficult for people to hit these small goals.
You decided how to fix it, to give people fat fingers and try to calibrate how fat to make them. Let's try to use a use case when a user tries to dial 1238. In (c) I increase the size of their finger as they arrive. Since the press on 8 covered the points of 8 and 0, I would say that it is too big.
(g)
(e)
(e)
(d) shows a reasonable size for calibration with this approach. Please note that 1 and 3 are still missing. 1 - miss simply because these buttons are not square. This is the limitation of this fat finger. 3 - miss, because the person really missed and pressed between the buttons. If you insist that 3 should be considered, I donโt know how we will do this without taking into account 2, 5 and 6. If you need this, we will need a rectangular collision detection. More on this later.
Assuming 3 should be considered a slip, I would like you to consider that (d) is mathematically identical (e). This can be achieved by simply adding tolerance to goals, rather than the user's finger. 1 and 3 are still overshot, but now, instead of calibrating the thickness of the user's finger, we only care about how large the goals are.
Simple thinking in this way gives us freedom so that our goals are not square. These are rectangles. Doing this in (f) corrects errors 1. If you have goals, they all have the same size and proportion, you don't have to deal with different tolerances x and y. If you want the flexibility of resizing to deal with this green button correctly, stop modeling the targets as one point. Model them using android.graphics.Rect . In fact, I would prefer that you model them with your own class that contains android.graphics.Rect , but I will pick up the OOP box another time.
Assuming you defined a target with new Rect(left, top, right, bottom) ] somewhere and assigned it to Rect r; , now you can find a hit with r.contains( (int) event.getX(), (int) event.getY() ); Since we already laid our nose on the OOP gods and rejected the idea of โโa button, I would say that for every click you make, it contains () through all the target tests.
(g)
Now, if you really insist that 2, 3, 5, and 6 should fire when the user skips 3, look at motionEvent.getSize() . This will measure the โfatnessโ of a touch from 0 to 1. If getToolMajor() or getTouchMajor() , they can help you evaluate the actual pixels affected. This may help to know the size, but as far as I can tell from the documentation, the pixel sizes created using any of them will be approximate. Some testing will help determine if it works as it is, or if constant scaling is needed. This is probably less than you expect, because they were designed for paint programs that give a bolder punch with extra pressure, and not to watch your fingertip collide with things.
Use this as tolerance to create another Rect around the click (lets call it fatFinger ). The r.intersects(fatFinger) test in a loop that supplies you with every r over your image. Every time it's true, you find another r .
That should give you something like (g). Now pressing 3 by pressing 2, 3, 5 and 6, pressing 1 presses 1 and 4, and pressing 8 - by 8 and 0.
Press 2 miraculously remains just 2 clicks away. Pulling it out is almost as difficult as hitting dots with dots. This may be good for your game, but please do not do this with my phone. :)
If you donโt want to go crazy, do a little OOP and create a class for your purposes that contains Rect, and provide your own intersection method supported by Rect one. This way you can encode them, get each t , and when t.intersects(fatFinger) is true, you can call your t.wasTouched();
In short, feed the targets, not the finger, if you do not want it to touch anything that is approaching. If so, feed both.
Regardless of whether you decide to go with (f) or (g), I think you will find much less need to adjust the finger size for the user if you take this approach. Happy coding!