matter-js icon indicating copy to clipboard operation
matter-js copied to clipboard

Detect that balls have hit the ground?

Open frankandrobot opened this issue 2 years ago • 2 comments

So I'm creating what's basically a billiards like environment with gravity---users can rotate their device and change gravity to match phone orientation. So for example, a user can tilt their device to the left and have all balls fall to the left.

Question: How can I tell if all the balls have fallen to a wall? Note that it's not enough to tell if the balls are touching the wall since they don't need to touch the wall directly to have fallen (they can stack). Also, because gravity varies by orientation, it's not enough to tell that all balls have stopped moving.

Off the top of my head, it seems that I have to build a graph --- root node is the wall. An object is a child node if it touches the parent node. So all the balls are on the floor when every ball is part of this graph.

Is there possibly a simpler way of doing this? Another idea is to query for orientation. Say the user has turned their phone to the left, within a delta, for X seconds. Thinking about this and I think that the second strategy might work.

But any other ideas?

frankandrobot avatar Aug 30 '21 21:08 frankandrobot

Yeah it really depends on your definition here. Could you just detect if they are 'resting' (and / or colliding)?

As a proof of concept maybe the easiest way for that would be to enable sleeping and check body.isSleeping or listen to the sleeping events. You probably would need to change some of the sleeping properties to make them sleep faster.

If that all works then I'd say look into the code of how Matter.Sleeping works to detect 'resting' (it involves some movement thresholding over time) and go from there.

Alternatively you could maybe use the body collision events to do something similar I think.

liabru avatar Sep 06 '21 09:09 liabru

Same use-case but body.isSleeping is not working.

I am not sure if this is a bug.

Here's the codepen.

As per https://github.com/liabru/matter-js/blob/master/src/core/Sleeping.js#L31 motion is being derived from body.speed while body.speed AFAIK is only ever being derived from Vector.magnitude(body.velocity).

Interestingly, calling Vector.magnitude(body.velocity) will indeed return 0 when I am perceiving the body as being at rest.

Edit: Apparently, setting engine.gravity is causing this issue by constantly applying force. In the codepen above the impact of engine.gravity appears to be too short-lived for it to show up in the metrics of that codepen.

However, as per @types/matter-js@^0.17.6 setting gravity is a requirement when providing options to Engine.create().

But even if it wasn't a requirement I would expect isSleeping to work...?

hahanein avatar Nov 28 '21 15:11 hahanein