Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Point in shape (graphic) hit test?
Started by dfoxinator Jul 09 2014 06:10 AM

12 replies to this topic
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

dfoxinator

[GLOBAL: userInfoPane.html]
dfoxinator
  • Enthusiast

  • 49 posts
  • Enterprise

Hi,

 

In basic terms, I want to be able to see if a point falls within the actual bounds (excluding transparent area of image) of a non-circular/rectangular graphical image. I want to accomplish this without the physics engine because I really don't have use for physics in my game and I want to keep it light.

 

What would be the most efficient way to do this? 

 

Any help is appreciated. 

 

Thanks,

~David



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,539 posts
  • Enterprise

Perhaps this API call would be of use:  http://docs.coronalabs.com/api/library/display/colorSample.html

 

It's close and resource expensive. 

 

Rob



[TOPIC: post.html]
#3

dfoxinator

[GLOBAL: userInfoPane.html]
dfoxinator
  • Enthusiast

  • 49 posts
  • Enterprise

Thanks, I was thinking of that as a possibility but the resource intensiveness is a problem.

 

I had an idea, but I'm not sure if it would work. Can I use a touch listener on the object (with mask), and then to test a point, dispatch a touch event at the specific coordinates to test?

 

Perhaps this API call would be of use:  http://docs.coronalabs.com/api/library/display/colorSample.html

 

It's close and resource expensive. 

 

Rob



[TOPIC: post.html]
#4

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,539 posts
  • Enterprise

If you're trying to use touch to determine, then masking the image becomes a real possibility.  A masked image will let touches fall through transparency and activate if it touches a non-transparent pixel.  This would let you now if the non-transparent pixels were touched and you would get an x, y as part of the event table.  You would get nothing for the transparent area unless you set up an invisible box underneath to capture the hit (.isVisible = false, .isHitTestable = true) then that event handler would get a touch event and you could compare the x, y with the object's rectangle if you needed to know if they touched a clear area of the rectangle.

 

Rob



[TOPIC: post.html]
#5

dfoxinator

[GLOBAL: userInfoPane.html]
dfoxinator
  • Enthusiast

  • 49 posts
  • Enterprise

Thanks, makes sense.

 

But my question is, if the touch event is dispatched programmatically, will it still fall through as it would with an actual touch? I think I'll just test this, but I'm trying to figure out if my logic is even remotely correct.

 

If you're trying to use touch to determine, then masking the image becomes a real possibility.  A masked image will let touches fall through transparency and activate if it touches a non-transparent pixel.  This would let you now if the non-transparent pixels were touched and you would get an x, y as part of the event table.  You would get nothing for the transparent area unless you set up an invisible box underneath to capture the hit (.isVisible = false, .isHitTestable = true) then that event handler would get a touch event and you could compare the x, y with the object's rectangle if you needed to know if they touched a clear area of the rectangle.

 

Rob



[TOPIC: post.html]
#6

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,539 posts
  • Enterprise

I don't believe you can generate a touch event programmatically like that.



[TOPIC: post.html]
#7

dfoxinator

[GLOBAL: userInfoPane.html]
dfoxinator
  • Enthusiast

  • 49 posts
  • Enterprise

So apparently triggering the touch event via dispatchEvent does in fact cause the listener to fire, but it still fires even if you trigger the event on the masked area :/ So it doesn't seem like that will work unless I'm missing something.



[TOPIC: post.html]
#8

bjsorrentino

[GLOBAL: userInfoPane.html]
bjsorrentino
  • Veteran

  • 8,506 posts
  • Corona SDK

Hi @dfoxinator,

Can you post your code for the dispatchEvent() and listener function, just so I can see if I spot anything unusual?

 

Thanks,

Brent



[TOPIC: post.html]
#9

dfoxinator

[GLOBAL: userInfoPane.html]
dfoxinator
  • Enthusiast

  • 49 posts
  • Enterprise

Sure Brent, thanks for looking.
 

The test code looks as follows:

 

For the test function:

local shape = display.newImage("test_shape.png", 0, 0);
shape.anchorX = 0;
shape.anchorY = 0;
local mask = graphics.newMask("test_mask.png");
shape:setMask( mask );

shape:addEventListener("tap", M.shapeTouched);
local event = { name="tap",  x=64, y=5, target=shape,time=1011,numTaps=1};
shape:dispatchEvent( event );

And then for the listener:

M.shapeTouched = function(event)
	print("TAP TRIGGERED");
end

The way I wanted this to behave was to not trigger the listener because the tap event is being dispatched with an x, y in the masked area. But the actual behavior is the shapeTouched handler is always called and TAP TRIGGERED always gets printed. It seems like the listener function gets called no matter where the coordinates are; even if they are way off of the image.

 

Another thing I tried was triggering a tap event on a graphic layer above this shape, hoping that maybe propagation would make it work right, but in that case the listener wasn't triggered at all.

 

Thanks for the help.



[TOPIC: post.html]
#10

bjsorrentino

[GLOBAL: userInfoPane.html]
bjsorrentino
  • Veteran

  • 8,506 posts
  • Corona SDK

Hi @dfoxinator,

I don't see that you've set ".isHitTestMasked". Is that somewhere else in your code?

 

Also, for the time being, can you use default (center) anchor on this? I don't think there's any conflict with masks and offset anchor points, but for testing, I'd like to eliminate that offset.

 

Thanks,

Brent



[TOPIC: post.html]
#11

dfoxinator

[GLOBAL: userInfoPane.html]
dfoxinator
  • Enthusiast

  • 49 posts
  • Enterprise

Thanks Brent. I tried setting isHitTestMasked to true and still no luck. I also got rid of the anchor point changing.

 

I think this is definitely some issue with the event dispatch method I'm using because actually clicking the shape produces the expected results, meaning when you click the masked off area it doesn't fire the listener but when you click the proper area it does.



[TOPIC: post.html]
#12

bjsorrentino

[GLOBAL: userInfoPane.html]
bjsorrentino
  • Veteran

  • 8,506 posts
  • Corona SDK

Yes, this is probably not supported (dispatching event while also honoring the hit mask).

 

If your shapes aren't incredibly complex, and you don't have to handle dozens or hundreds of varieties, could you build vector polygons that basically surround the touchable area, and overlay those (invisible but hit-testable) over the images?

 

Brent



[TOPIC: post.html]
#13

dfoxinator

[GLOBAL: userInfoPane.html]
dfoxinator
  • Enthusiast

  • 49 posts
  • Enterprise

Yeah, that's definitely an option. Either that or just plot some points to form border lines. It would be a really good feature though, to have a function that could test whether a single point intersects with an object. This is something Flash has which is very useful.

 

Thanks for the advice.




[topic_controls]
[/topic_controls]