Can I detect custom-shaped touch events using physics bodies (or anything other than masks)?

Say, I had a star shaped sprite and I wanted to add a touch event that is only triggered when the touch is within the star shape… not the whole sprite rectangle which includes the star.

Is there a way to use the physics body (shapes or outlines) to detect touch events for custom shapes? Or are masks the only option?

Thank you.

Hi @jhow,

Masks are probably the best option, but if you want to avoid that entirely, then I suppose you could have a very small physics sensor object, and when the user touches, you move that to the touch point, detect if it collides with the star, and if yes then you know the user touched essentially within the bounds of the star’s physics body.

Take care,

Brent

This means, though, that I would have to resolve the event using collision API (in addition to the touch API), correct?

This might have the potential to make it a bit more complicated to coordinate with touch.move events… For example, say I wanted the following hypothetical interactivity, which would ideally be performed within a single handler tied to a local _ touch _ eventListener

  1. touch the star (within custom shape only) - began --> star pops into foreground
  2. move finger - moved --> star follows finger
  3. ended --> star snaps in to background in end position

In contrast, if I understand correctly, using the proposed collision object (_ sensor _) would work as follows?

  1. I touch somewhere on the star sprite
  2. Within my _ touch _ handler, I create/move a small physics sensor to my event.x, event.y
  3. Assuming the sensor does not collide with the star, nothing happens. Assuming the sensor collides with the star -->  outside the touch handler , a collision event is created.
  4. Inside _ collision _ event - _ began _ --> pop star into foreground, setFocus of _ touch _ event to star
  5. Back inside _ touch  _event - _ moved _ --> if focus of _ touch _ event is set to star then star follows finger (Since the star moved, does the collision event end? )
  6. Inside _ touch _ event - _ ended _ --> snap star in place, set focus of touch event to nil
  7. Assuming there’s a _ collision _ _ ended _ phase in there --> has no effect

Would that solution be that roughly correct?

Most importantly, is there a way I can resolve my touch handling within my touch handler exclusively rather than using a collision handler? Is there some type of functionality where I can just do something simple like starBody:containsPoint(event.x, event.y) within my touch handler? That way I don’t need to create a near-useless collision and coordinate both touch and collision events? 

Thank you so much. Your advice would be greatly appreciated!

Hi @jhow,

Your scenario is basically correct, except that you probably don’t need to worry about any collision phase except for “began”. This means that the user touched somewhere within the star’s body, and once that occurs, you just take control of its movement/dragging in the touch handler, exactly as you would normally. Yes, you would get an “ended” collision when the star moves outside the little sensor dot, but it’s irrelevant at that time so you shouldn’t even detect it.

Best regards,

Brent

P.S. - No, there isn’t any way that I know of to detect a “touch within bounds” without using a mask. Well, I suppose there would be a math formula for the basic shapes, but something complex like a star would be extremely difficult to mathematically check points within.

Hi @jhow,

Masks are probably the best option, but if you want to avoid that entirely, then I suppose you could have a very small physics sensor object, and when the user touches, you move that to the touch point, detect if it collides with the star, and if yes then you know the user touched essentially within the bounds of the star’s physics body.

Take care,

Brent

This means, though, that I would have to resolve the event using collision API (in addition to the touch API), correct?

This might have the potential to make it a bit more complicated to coordinate with touch.move events… For example, say I wanted the following hypothetical interactivity, which would ideally be performed within a single handler tied to a local _ touch _ eventListener

  1. touch the star (within custom shape only) - began --> star pops into foreground
  2. move finger - moved --> star follows finger
  3. ended --> star snaps in to background in end position

In contrast, if I understand correctly, using the proposed collision object (_ sensor _) would work as follows?

  1. I touch somewhere on the star sprite
  2. Within my _ touch _ handler, I create/move a small physics sensor to my event.x, event.y
  3. Assuming the sensor does not collide with the star, nothing happens. Assuming the sensor collides with the star -->  outside the touch handler , a collision event is created.
  4. Inside _ collision _ event - _ began _ --> pop star into foreground, setFocus of _ touch _ event to star
  5. Back inside _ touch  _event - _ moved _ --> if focus of _ touch _ event is set to star then star follows finger (Since the star moved, does the collision event end? )
  6. Inside _ touch _ event - _ ended _ --> snap star in place, set focus of touch event to nil
  7. Assuming there’s a _ collision _ _ ended _ phase in there --> has no effect

Would that solution be that roughly correct?

Most importantly, is there a way I can resolve my touch handling within my touch handler exclusively rather than using a collision handler? Is there some type of functionality where I can just do something simple like starBody:containsPoint(event.x, event.y) within my touch handler? That way I don’t need to create a near-useless collision and coordinate both touch and collision events? 

Thank you so much. Your advice would be greatly appreciated!

Hi @jhow,

Your scenario is basically correct, except that you probably don’t need to worry about any collision phase except for “began”. This means that the user touched somewhere within the star’s body, and once that occurs, you just take control of its movement/dragging in the touch handler, exactly as you would normally. Yes, you would get an “ended” collision when the star moves outside the little sensor dot, but it’s irrelevant at that time so you shouldn’t even detect it.

Best regards,

Brent

P.S. - No, there isn’t any way that I know of to detect a “touch within bounds” without using a mask. Well, I suppose there would be a math formula for the basic shapes, but something complex like a star would be extremely difficult to mathematically check points within.