Part 3a – A Factory to make Prefab bodies

Today we will improve the way we create Body instances in our physics world.

This is how we created them in Part 1:

//Create 2 boxes
Body box1 = BodyFactory.CreateRectangle(_world, 0.4f, 0.4f, 1f);
box1.Position = new Vector2(4, 0.75f);
box1.BodyType = BodyType.Dynamic;
box1.UserData = "box1"; // <-- the name of the texture as it was called originally
_bodies.Add(box1);
Body box2 = BodyFactory.CreateRectangle(_world, 0.4f, 0.4f, 1f);
box2.Position = new Vector2(4.2f, 0.0f);
box2.BodyType = BodyType.Dynamic;
box2.UserData = "box2"; // <-- the name of the texture as it was called originally
_bodies.Add(box2);

As you can see, a lot of code repetition and if we were to add more boxes, the repetition would only get worse.

To solve this issue, we will move the creation of new Body instances into its own specialized class: PrefabBodyFactory.

Indeed, if you look at a typical level in Angry Birds, you notice the same type of Body is reused several times:

Our PrefabBodyFactory will have only one public method.

/// <summary>
/// Create Body of certain prefab type
/// </summary>
/// <param name="type">prefab type</param>
/// <param name="world">Farseer world</param>
/// <param name="position">position of the body in the physics world (using simulation coordinates)</param>
/// <returns>a new instance of a Body</returns>
public static Body CreateBody(PrefabType type, World world, Vector2 position)

PrefabType is an enum, which will contain all our types of bodies.
In our example, we have two types of boxes so far: a golden one and a gray one. This means PrefabType looks like this:

public enum PrefabType
{
    GoldBox,
    GrayBox,
}

Time to take a look at PrefabBodyFactory.
The underlying idea is that we have a library of predefined shapes and each time we ask the factory to create a new instance of one of known types from the library.
This library is be implemented as Dictionary with as key our PrefabType enum and as value a delegate which takes the Farseer World and a position as input and returns a new Body.
In other words: our library is not a library of predefined shapes, but a library of methods creatings predefined shapes. This is important when we start to make a lot of instances of the same PrefabType: every instance should be a new instance.

/// <summary>
/// The PrefabBodyFactory will create new Body instances with specific, predefined settings
/// </summary>
public class PrefabBodyFactory
{
    private static readonly Dictionary<PrefabType, Func<World, Vector2, Body>> Library = new Dictionary<PrefabType, Func<World, Vector2, Body>>();
}
 /// <summary>
 /// Static constructor will initialize our library of prefab-shapes
 /// </summary>
 static PrefabBodyFactory()
 {
     Library.Add(PrefabType.GoldBox, (world, position) => CreateRectangle(world, position, "box1", 0.4f, 0.4f));
     Library.Add(PrefabType.GrayBox, (world, position) => CreateRectangle(world, position, "box2", 0.4f, 0.4f));
}
 /// <summary>
 /// Create Body of certain prefab type
 /// </summary>
 /// <param name="type">prefab type</param>
 /// <param name="world">Farseer world</param>
 /// <param name="position">position of the body in the physics world (using simulation units)</param>
 /// <returns>a new instance of a Body</returns>
 public static Body CreateBody(PrefabType type, World world, Vector2 position)
 {
     //will lookup the correct delegate in our prefab library and execute the delegate in order to create a new instance
     return Library[type](world, position);
 }

 /// <summary>
 /// Create a body with a rectangular shape
 /// </summary>
 /// <param name="world">World</param>
 /// <param name="position">Position in sim-units</param>
 /// <param name="spriteName">Sprite name to render with</param>
 /// <param name="width">width of the body in sim-units</param>
 /// <param name="height">height of the body in sim-units</param>
 /// <returns>new instance of a Body</returns>
 private static Body CreateRectangle(World world, Vector2 position, string spriteName, float width, float height)
 {
     Body body = BodyFactory.CreateRectangle(world, width, height, 1f, position);
     body.UserData = spriteName;
     body.BodyType = BodyType.Dynamic;
     return body;
 }
}

Given this new PrefabFactory we can now replace our original code with this:

//Create 2 boxes
Body box1 = PrefabBodyFactory.CreateBody(PrefabType.GoldBox, _world, new Vector2(4, 0.75f));
_bodies.Add(box1);
Body box2 = PrefabBodyFactory.CreateBody(PrefabType.GrayBox, _world, new Vector2(4.2f, 0.0f));
_bodies.Add(box2);

Give it a run and you’ll see the behaviour is still the same as before, but our code has become much cleaner.

In the next part we will finetune our PrefabFactory and Draw method in order to support more shapes types.

Advertisements

11 Responses to Part 3a – A Factory to make Prefab bodies

  1. Mike says:

    I don’t remember having issues specifically with Library. I would share my solution with you if it is alright with the author. I’ve completed up to part 5.

  2. Mike says:

    I’m stuck. I have a bunch of errors and I don’t know where to go for help. I’m an integrator with a graphic design background so XAML and Blend are my best friends. For this project I have been using VS 2010 but there is just too much left out for a coding noob like me to figure it out. I’m excited about the tutorial please help me get to the next step!

    • Mike says:

      Now that some of my developper friends have helped me out I’m really starting to enjoy this tutorial! I’m currently on step 4c.

      • Chuck says:

        Do you remember what you did to fix the errors? I have a bunch on errors on any line that contains “Library” in the above code.

        Thank you.

  3. Pingback: ??? ?? ????? ????? 29-?? ????! ?? ??????? «????????» ????! - MSDN Blogs

  4. jerry says:

    What is a Library in the public class PrefabBodyFactory? I’m new to windows phone. I know c#, so where is the variable or class/object type Library declared or coded?

  5. Yakyb says:

    The Curly brackets on Line 7 need removing i think

  6. agata says:

    hi i have many problem with it, is simewhere there all code game in subject to download?

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

%d bloggers like this: