Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Keep existing contacts on shape updates #46

Closed
Fxlr8 opened this issue Nov 6, 2018 · 5 comments
Closed

[Question] Keep existing contacts on shape updates #46

Fxlr8 opened this issue Nov 6, 2018 · 5 comments

Comments

@Fxlr8
Copy link

Fxlr8 commented Nov 6, 2018

Hi, I am making a top-down view multiplayer game and I have a lot of objects on my map. The map is bigger than the player's screen, so one player can only see a part of a map.

When I am sending updates to the player I want to send him only the objects he can see to prevent him from cheating by zooming out. The most convenient solution that I found was to create a screen-sized sensor shape around the player. When this sensor begins a contact with an object, this means the player can see it and I can send it to the client. When the contact ends this means that the object disappeared from the player's screen and should be removed from the client's state.

This was a perfect solution, which saved me from storing arrays of everything a player can see and compare it with the new one on every tick to find what was added/removed from the screen. But, unfortunately player field of view can change over time. Shapes can't be updated in box2d. This means i have to delete an old screen shape and create a new one. When this happens, every contact with this shape is deleted and created again. Is there a solution for this case? Bodies involved in this contact didn't change, only their shapes did. What i want here is to track contacts by bodies not by shapes. I don't need any normals or something, only a boolean are they still touching or not.

@flyover
Copy link
Owner

flyover commented Nov 6, 2018

Try modifying the shape connected to the fixture then call fixture.Synchronize() using the transform from fixture.GetBody() for both transforms.

const shape: box2d.b2PolygonShape = fixture.GetShape() as box2d.b2PolygonShape;
shape.SetAsBox(...);
fixture.Synchronize(fixture.GetBody().GetTransform(), fixture.GetBody().GetTransform());

I suppose the b2Fixture:Synchronize method could be changed to use this as the default arguments.

@Fxlr8
Copy link
Author

Fxlr8 commented Nov 8, 2018

This works perfectly, thank you!

@jcyuan
Copy link

jcyuan commented Nov 12, 2018

cool, I actually have the same question, I have to change shapes when the character is performing into another state for example fro run to slide, I can successfully modify the vertices of the shapes but it seems the changes will be applied in next frame tick.
let me try the Synchronize method, thank you.

@jcyuan
Copy link

jcyuan commented Nov 17, 2018

it works perfect. thanks.

@Fxlr8 Fxlr8 closed this as completed Nov 28, 2018
@Fxlr8
Copy link
Author

Fxlr8 commented Dec 3, 2018

By the way, creating a sensor for every player's screen was a terrible idea performance-wise. You should prevent every single body from sleeping so it could detect contacts with the sensor. And it becomes even worse when you have to change that shape's size or position. It causes a lot of resources to recalculate all the contacts of that sensor. I returned for AABB queries and everything is super fast.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants