Making Pong using Farseer Physics engine

In my attempt to learn farseer physics engine(3.2), I decided to make a pong game, using the engine and XNA 4.0. Physics engine is an overkill for pong, but it sure helps to learn some of the basic concepts in a simple environment.

Please see my last post about some of the basic knowledge you need to get started.

This post is not about software design, and this is just my way of doing things.

Setting up the world:

I made a CollisionManager which contains the World from FPE, and exposes it as a property which others can use.

Creates a world with no gravity:

   1: mWorld = new World(Vector2.Zero);

In CollisionManager.Update(gameTime); ticks the world:

   1: mWorld.Step((float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.001f);

By default, forces are automatically cleared in FPE, but in Box2D it is recommended to clear the forces.

   1: mWorld.ClearForces();

That is it! We’re done setting up the world.

Setting up the Ball:

GameOjbect just contains a reference to Body

   1: public class Ball : GameObject

Setting up the body:

   1: mBody = BodyFactory.CreateBody(CollisionManager.Instance.Worldphy, new Vector2(10, 0));

   2:  

   3: mBody.CreateFixture(new CircleShape(1.0f, 0.5f ));

   4:  

   5: mBody.FixtureList[0].Restitution = 1f;

   6:  

   7: mBody.BodyType = FarseerPhysics.Dynamics.BodyType.Dynamic;

   8:  

   9: mBody.ApplyLinearImpulse(new Vector2(50, 0));

  1. Create a body in world at vector2(10, 0)
  2. Creates a fixture out of a shape for mBody:
    1. A circle shape with a radius of 1.0f is created
    2. Density is 0.5f
  3. For the fixture attached to body, we want to set the restitution. Restitution is a measure of bounciness of a collision (elasticity of collision). Value should be between 0 and 1.
    1. 0 = fully absorb the collision : dont bounce at all : inelastic collision
    2. 1 = perfect reflection : fully bounce back : elastic collision
  4. Setting the bodyType to be Dynamic
  5. Give the ball an initial ‘impulse’

Setting up a Paddle:

Paddle also inherits from GameObject:

   1: public class Paddle : GameObject

Setting up the body:

   1: Fixture fix = FixtureFactory.CreateRectangle(CollisionManager.Instance.Worldphy, 1, 3, 0.5f, posn);

   2: fix.Restitution = 0f;

   3: fix.Friction = 0f;

   4:  

   5: mBody = fix.Body;

   6: mBody.BodyType = BodyType.Dynamic;

This time we choose to create a body using fixtures.

  1. Create a fixture in world, with a body at position: ‘posn’ and rectangle shape of width 1 unit and height 3 units (units are in the MKS system) (I pass the posn as a vector2 in the constructor of Paddle)
  2. We want the restitution to be 0 since we dont want the paddle to bounce off. See above for what restitution is!
  3. Assign the body reference in fixture to body of parent GameObject
  4. Make the BodyType to be dynamic

Moving the paddle:

   1: if (Input.IsNewKeyPress(Keys.W))

   2: {

   3:     mBody.ApplyForce(new Vector2(0f, 10.0f));

   4: }

   5: else if (Input.IsNewKeyPress(Keys.S))

   6: {

   7:     mBody.ApplyForce(new Vector2(0f, -10.0f));

   8: }

When W is pressed, we want the paddle to move up (we apply a force in up direction with magnitude of 10f). When S is pressed, we want the paddle to move down (we apply a force in down direction with magnitude of -10f).

 

That’s it. Instantiate a paddle and a Ball and you’ll see a ball moving towards right and if you press W/S the paddle would move either up/down.

You’ll also notice the ball to fly off the screen because there is nothing to bound it. I used this code from one of the testSamples for farseer to generate a big box, which would prevent the ball or paddle to fly away.

   1: List<Vertices> borders = new List<Vertices>(4);

   2:  

   3: const float borderWidth = 0.2f;

   4: const float width = 40f;

   5: const float height = 25f;

   6:  

   7: //Bottom

   8: borders.Add(PolygonTools.CreateRectangle(width, borderWidth, new Vector2(0, height), 0));

   9:  

  10: //Left

  11: borders.Add(PolygonTools.CreateRectangle(borderWidth, height, new Vector2(-width, 0), 0));

  12:  

  13: //Top

  14: borders.Add(PolygonTools.CreateRectangle(width, borderWidth, new Vector2(0, -height), 0));

  15:  

  16: //Right

  17: borders.Add(PolygonTools.CreateRectangle(borderWidth, height, new Vector2(width, 0), 0));

  18:  

  19: List<Fixture> fixtures = FixtureFactory.CreateCompoundPolygon(mWorld, borders, 1, new Vector2(0, 0));

  20:  

  21: foreach (Fixture fixture in fixtures)

  22: {

  23:     fixture.Restitution = 1f;

  24:     fixture.Friction = 0;

  25: }

By default, the bodyType is static, which is what we’d want the outer box to be.

The code is very intuitive if you followed the above post and read the basics in my last post.

About these ads

3 Comments on “Making Pong using Farseer Physics engine”

  1. Jasper says:

    very nice! what do you think of Farseer vs the standard Box2D suite?

    I am currently using Box2D XNA, with very minor mods, but i am curious about what I may gain by using farseer instead?

  2. brainydexter says:

    For one, there is more support in the Farseer community and it has been in development for three years now! Last I checked, I think farseer was syncd to a later revision of the original box2d, compared to box2d.xna.

    The community even implemented some code for convex decomposition etc, which I’m not sure if Box2D xna does.

  3. brainydexter says:

    Also, I don’t know if you saw this, but I’ll repost the link anyways. They briefly go over how they differ from the standard box2D.

    http://farseerphysics.codeplex.com/wikipage?title=Differences%20between%20Box2D%20and%20Farseer%20Physics%20Engine%203.0&referringTitle=Tutorials


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.