Code-only Farseer Introduction

Introduction

The Farseer Physics Engine is a physics engine (as the name implies) written in C#. It is directed toward use with XNA and Silverlight, but it can be used with any .NET application. It is a common choice for expanding the physics capabilities of FlatRedBall.

General Approach

Unfortunately the tutorial support for Farseer (at the time of this writing) is a little lacking. However, once the basic behavior is set up, following the samples provided on the Farseer site (with the downloaded .zip below) is not too difficult.

In general, the following must be done to set up Farseer:

  1. Instantiate and step forward a World – The World can be created in the Initialize method of your game and Updated in the Update method.
  2. Create a Body – A Body is created through Farseer’s Factory classes. The Body must be added to the World.
  3. Set properties for Body – You can set properties such as size, orientation, velocity, and how the bodies respond to collisions (inertia, elasticity, friction).

Fortunately, the interaction between FlatRedBall and Farseer is fairly straight-forward. At a high level, all that needs to happen once the Farseer physics is set up is PositionedObjects need to be updated according to the farseer positions and rotations.

Downloading Farseer

Farseer can be found at the following address:

http://www.codeplex.com/FarseerPhysics

Perform the following steps to prepare using Farseer:

  • Click on the “Download” button on the right side of the page posted above.
  • Download the .zip file somewhere on your computer.
  • Unzip the newly-downloaded zip file.

The unzipped file contains the necessary .cs files as well as the project file which you can add to your game’s solution.

Assuming you have an already-created project that links to FlatRedBall, perform the following steps to add Farseer:

  • Right click on the solution name in the Solution Explorer
  • Select Add->Existing Project…
  • Navigate to the location where you unzipped the Farseer zip file.
  • Select the project file (FarseerPhysics.csproj) and click the “Open” button.
  • Right-click the “References” folder under your game project.
  • Select “Add Reference…”
  • Select the “Projects” tab.
  • Select “FarseerPhysics” and click the “OK” button.

Rebuild to make sure that everything is set up correctly.

Code Example

The following code example sets up a simple Farseer environment, then adds two FlatRedBall objects which will serve as the visible representation for these Farseer objects. We are currently using Farseer version 3.3.1.

Add the following using statements:

using FlatRedBall.Math.Geometry;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;

Add the following fields at class scope:

//Farseer Objects
World mWorld;
Body mBallBody;
Body mPlatformBody;

//FlatRedBall Objects
Sprite mBallSprite;
Polygon mPlatformPolygon;

Add the following to Initialize after inititalizing FlatRedBall:

//Farseer
float gravity = -4;
mWorld = new World(new Vector2(0, gravity));

//Create a ball body with a radius of 1 and density of 1
mBallBody = BodyFactory.CreateCircle(mWorld, 1, 1);
mBallBody.Restitution = 1f;
mBallBody.BodyType = BodyType.Dynamic;

//Create a rectangle platform with a width of 40, height of 3,
//density of 1, and position at 0, -12
//Then set the position and rotation
mPlatformBody = BodyFactory.CreateRectangle(mWorld, 40, 3, 1, new Vector2(0, -12));
mPlatformBody.Rotation = .1f;
mPlatformBody.Restitution = 1f;
mPlatformBody.IsStatic = true;

//FRB
mPlatformPolygon = Polygon.CreateRectangle(20, 1.5f);
mPlatformPolygon.X = mPlatformBody.Position.X;
mPlatformPolygon.Y = mPlatformBody.Position.Y;
mPlatformPolygon.RotationZ = mPlatformBody.Rotation;
ShapeManager.AddPolygon(mPlatformPolygon);

mBallSprite = SpriteManager.AddSprite("redball.bmp");
mBallSprite.X = mBallBody.Position.X;
mBallSprite.Y = mBallBody.Position.Y;

Add the following to Update:

//Farseer: Only need to step (update) the world you added the objects to
mWorld.Step(TimeManager.SecondDifference);

//FRB: Don't forget to update the visual representations as well!!
mBallSprite.X = mBallBody.Position.X;
mBallSprite.Y = mBallBody.Position.Y;

//mPlatformPolygon is static (doesn't move), so there is no need to update its position

FarseerIntegration.png

The full example can be downloaded here.

Understanding Units

If you’re familiar with the default 3D FlatRedBall Camera then you know that one unit does not necessarily equal one pixel. So, you may be wondering how Farseer units line up with FlatRedBall units. Unless you use the debug drawing for Farseer, the units in Farseer have absolutely no connection to any rendering. That means that you as the user can define what the relationship should be between FlatRedBall units and Farseer units. The simplest relationship is one where the units reflect each other with no conversion.

In other words, by default the units will automatically line up perfectly. In the example above, the mBallSprite and mPlatformPolygon objects are simply positioned to the same position as the Farseer Body objects. Similarly, rotation values also line up perfectly since Farseer uses radians just like FlatRedBall.

It’s important to notice that the Farseer BodyFactory.CreateRectangle method uses width and height while FlatRedBall objects use ScaleX and ScaleY. That’s why the values in the FRB Polygon.CreateRectangle call are half of the values in BodyFactory.CreateRectangle.

Farseer and different versions of XNA

If you are seeing a message that says:

Xnaerror.jpg

You may be able to resolve this problem by either upgrading the Farseer project that you are referencing (if you are using the source code) or simply linking to the prebuilt DLLs. For more information, see this thread on our forums.