Need Mask For Hit Area On Button But Don't Want Visual Effect Of Mask

The only info I’ve been able to find about making just part of an image hittable is to create a mask for the hit area and apply the mask to the object. The problem with this method is that it then masks the rest of the image from view. I need ALL of the image to show, but only PART of the image to be touchable.

Can that be done?

I don’t want to break it into multiple images. Essentially I need the shadow behind the button in the image to show but not be touchable/react to touch. If I have to break the shadows out of all of the buttons it will literally double the amount of work as well as double the amount of images, memory, etc etc.

I can’t imagine there isn’t a way to make a portion of an image receive touch without having to mask out the rest of the image and not have it show. But I couldn’t find any info anywhere. Something like a basic image map in html.

Hi @tim41,

As you’ve found, bitmap masks hide parts of the image as well as mask the touch area. One possible solution would be to create an overlaying rectangle that matches the size of the button, and apply the mask and touch listener to that instead of the button. Another option, if your “touch area” is basically rectangle, is to use math to determine if the touch x and y are within the region you want, in respect to the button’s x and y position. You could even do this with a triangular region I suppose, but the math would be a bit slightly more involved.

Hope this helps, at least somewhat.

Brent

Hi Brent - thanks for quick response.

Unfortunately the button is round within a larger rectangle image. I found a workaround that seems fine.

I added a second instance of the image underneath the first one. I masked the top one and added the touch listener to that one. So the button shows through and is hittable on the top image, the rest is masked. The same image is then underneath that one and you can see the rest of the image on that one. It’s a bit wonky/messy to have duplicate copies of the same image on top of each other, but it does work.

It did occur to me later the other way to do it would be to draw a rectangle on top of the image as you suggested but I wasn’t sure if I then made the rectangle transparent in order to see the image through it, if it would still receive touch while transparent or if a mask can be applied to a transparent object.

I figured the way I did it does take up a bit more memory with two of each button on screen at a time on top of each other, but both objects are being created from the same underlying .png in an imagesheet, so I assume it won’t add anything/much to the file size really or change performance much? I also don’t know if there will be any ramifications relative to other systems like Android.

Hi @tim41,

I thought of a new solution, since the touch region is round. You can just put a vector circle as the region, on top of the image, set it to invisible, and put the touch listener on that object. BUT, since it’s invisible, you must also set the “.isHitTestable” property to “true”. By default, invisible images no longer accept touch/tap responses, but you can reverse that behavior by explicitly setting this property.

[lua]

local circle = display.newCircle( 100,100,50 )
circle.isVisible = false
circle.isHitTestable = true

[/lua]

This should be much more efficient than a mask and doubling the image.

Best of luck!

Brent

I implemented your invisible circle solution instead and it works perfect. Thanks Brent.

Hi @tim41,

As you’ve found, bitmap masks hide parts of the image as well as mask the touch area. One possible solution would be to create an overlaying rectangle that matches the size of the button, and apply the mask and touch listener to that instead of the button. Another option, if your “touch area” is basically rectangle, is to use math to determine if the touch x and y are within the region you want, in respect to the button’s x and y position. You could even do this with a triangular region I suppose, but the math would be a bit slightly more involved.

Hope this helps, at least somewhat.

Brent

Hi Brent - thanks for quick response.

Unfortunately the button is round within a larger rectangle image. I found a workaround that seems fine.

I added a second instance of the image underneath the first one. I masked the top one and added the touch listener to that one. So the button shows through and is hittable on the top image, the rest is masked. The same image is then underneath that one and you can see the rest of the image on that one. It’s a bit wonky/messy to have duplicate copies of the same image on top of each other, but it does work.

It did occur to me later the other way to do it would be to draw a rectangle on top of the image as you suggested but I wasn’t sure if I then made the rectangle transparent in order to see the image through it, if it would still receive touch while transparent or if a mask can be applied to a transparent object.

I figured the way I did it does take up a bit more memory with two of each button on screen at a time on top of each other, but both objects are being created from the same underlying .png in an imagesheet, so I assume it won’t add anything/much to the file size really or change performance much? I also don’t know if there will be any ramifications relative to other systems like Android.

Hi @tim41,

I thought of a new solution, since the touch region is round. You can just put a vector circle as the region, on top of the image, set it to invisible, and put the touch listener on that object. BUT, since it’s invisible, you must also set the “.isHitTestable” property to “true”. By default, invisible images no longer accept touch/tap responses, but you can reverse that behavior by explicitly setting this property.

[lua]

local circle = display.newCircle( 100,100,50 )
circle.isVisible = false
circle.isHitTestable = true

[/lua]

This should be much more efficient than a mask and doubling the image.

Best of luck!

Brent

I implemented your invisible circle solution instead and it works perfect. Thanks Brent.

I used the same trick for our round Freeze-button and it works perfect. Very simple solution, Thanks!

Best,

Andreas

I used the same trick for our round Freeze-button and it works perfect. Very simple solution, Thanks!

Best,

Andreas