flyover / box2d.ts

A TypeScript port of Box2D
https://flyover.github.io/box2d.ts/testbed
MIT License
405 stars 85 forks source link

[Question] How to make sleeping bodies interact with sensors? #47

Closed Fxlr8 closed 5 years ago

Fxlr8 commented 5 years ago

Hi, this question is about the same game I was talking about in #46

TL;DR (#46) a top-down online game, rectangle-shaped sensor body around the player used to register objects in the world that shoud be sent to that player.

I faced the following problem: When the screen stops intersecting with a coin (and moves far away from it), sometimes the contact object is still there, it is still active and still thinks that it is touching.

Screen is a static body with a box shaped sensor. This body is moved to the player position on every tick.

A coin is a sleeping dynamic body with a circle shape.

What can cause this?

Fxlr8 commented 5 years ago

I investigated this case a little more and found, that this problem is related to body sleeping. I disabled coins sleeping and the contacts work fine now. But sleeping is disabled now. The whole point of these screen objects was to optimize game state extraction for each player. If sensor collision detection works only when the bodies are not sleeping, then I have to disable sleeping for all objects in my game. This will make my optimization attempt pointless and produce even more computational overhead. Is there any way to make sleeping bodies interact with sensors?

jcyuan commented 5 years ago

this is normal behavior of box2d.

Solutions from box2d forum:

  1. Create all physics bodies with allowSleep = false.
  2. do a b2World::QueryAABB within the range of the sensor, and check for any sleeping bodies, and call b2Body::SetAwake on those bodies (which should hopefully invoke the event callback).
Fxlr8 commented 5 years ago

But the bodies won't be able to fall asleep naturally. I can make them fall asleep manually when the contact ends, but this leads to a painful scenario when screens of two or more players intersect. The first thing that comes to my mind is to add a counter to every entity which stores how many players actually see it. And when it comes to zero, the body finally falls asleep. What if a moving body falls asleep? Will it keep moving or just stops?