Moving from Box2D to Farseer

Topics: User Forum
Dec 29, 2010 at 7:44 AM
Edited Dec 29, 2010 at 7:47 AM

Hi everyone-

 

I've done a LOT of work with Box2D, in objective-C++ for the iPhone and iPad wrapped in Cocos2D.  I'm switching gears to C#/XNA/Farseer now and trying to wrap my head around what the standard practice is for integrating physics in a game.

Basically, in Box2D working in Obj-C++, I basically do something like this:

  1. Create bodies and fixtures in an initialization function, and set an object to the UserData pointer to reference later
  2. In the game loop, iterate through the bodies, looking at the UserData to figure out what kind of object we have, and dealing with it in a big if/else if/else list.
  3. If an object goes out of bounds, remove the body from the world and delete the object stored in UserData
  4. Handle collisions in a separate ContactListener class which makes calls back to the main game object.

I'm getting the feeling that I should be looking at Farseer very differently than Box2D, since I'm running into brick walls everywhere I turn.  Anyone else making or made the switch?

My first problem is that I'm trying to simply figure out a way to iterate through the bodies and remove them if, say, they go out of bounds.  At what point can they be removed from the world?  I get exceptions thrown when I try to do it the way I've always done it, e.g. in Update I would do something like this:

 

foreach (Body body in world.BodyList) {
  PhysicsObject physObj = (PhysicsObject)body.UserData;

  if (physObj.Position.Y > ScreenManager.GraphicsDevice.Viewport.Height) physObj.isFlaggedForRemoval = true;
  else if (physObj.isFlaggedForRemoval) world.RemoveBody(body);                  
}

 

But I get exceptions when I make the removeBody call.   I have read that perhaps I should set the isFlaggedForRemoval to true and then handle removing the object in the PhysicsObject's Update function.  Then should my physics body wrapper class be a GameComponent?  I'm just trying to get a feel for how people generally wrap and manage their physics objects and how they relate them to XNA objects and components.

Hopefully that's not too vague a question.  I have a feeling anyone who has worked with Box2D in C++ might have similar confusion. Perhaps a more specific set of questions is:

  • What do the wrapper classes for your body and fixtures look like?  Components with Update and Draw?  Simple struct like classes? Something else?
  • When and how are objects removed from the world safely?

I read elsewhere in this forum that in 3.2 the remove body calls will be buffered and handled on the next world step.  But I still would like to know when the "right" time to do these things is.

Dec 29, 2010 at 8:30 AM

Updating to Change Set 82480 fixed the RemoveBody problem.  Perfect!  I'm definitely still curious about how people are wrapping the Farseer physics objects though.


And I see that collisions can be handled very easily with delegate methods.  I would like to write up a little Box2D->Farseer article this week as I plow though this.

Coordinator
Dec 29, 2010 at 12:49 PM

The removal of bodies should be done in the same way as in Box2D:

In your collision callback, you mark the body as deleted. Once the physics step is done, you remove the body. We need to do it this way because the body you are trying to remove is being used inside the engine - and removing it will cause a bunch of problems.

However, as you mentioned yourself, I've implemented a change-caching system that caches both added and removed bodies in the engine. Once on every step it evaluates the cache and adds/removes the changes. This creates other problems such as changes does not take effect until the next step - so if you decide to remove a body/fixture inside the physics step, you will have to deal with that instead.

As you found out yourself, we do not have a contact listener as Box2D does. We use delegates instead that when subscribed, does the callback directly to your physics objects. I've also implemented access to a bunch of other callbacks on a per fixture basis: BeforeCollision and AfterCollision are good examples. (available in FPE 3.2).

As for the wrapper - normally you would create a list of game objects that has an Update and Draw method. GameComponents should only be used for self contained pieces of logic like a FPS counter. Take a look at the samples in FPE if you need a good reference.

Dec 30, 2010 at 4:33 AM
Edited Dec 30, 2010 at 4:33 AM

Thanks Genbox.  Yeah it looks like with 3.2 we'll be able to do things almost the same as I'm used to with Box2D.  But even with 3.1 there is a lot the same.  A lot to like about Farseer for sure.  I'm having a blast learning it.

For anyone who's curious about making the switch, I made a demo project using Farseer 3.1 that looks almost the same as a Cocos2D/Box2D project might be set up (or, at least the way I do mine when working with Cocos2D).  The project is here: http://thedeadlings.com/2010/12/30/an-xna-template-using-farseer-3-1-xna-4-0-and-gamestatemanagement/

In terms of removing the bodies, I went with adding the to an object list and giving them each an update and draw method, so the objects can remove themselves from the world and the object list as needed in their update method.  This is a little different from how I did it with Box2D, where you iterate through all of the bodies in the world, pull out their wrapper object using UserData, and process them.  You can actually just remove them from the world in this loop, but that causes errors in Farseer (it doesn't in the newest code, thanks to the buffering stuff, but the I like the way the objects handle their own cleanup now).


Anyway, I think there is some interesting stuff in that sample project, it was pretty much everything I needed to get up to speed. Anyone like me switching from Cocos2D/Box2D to XNA/Farseer might find it useful :)