SyntaxHighlighter

Saturday 5 March 2011

Quick 2d terrain with Farseer

This is going to be a quick tutorial on one approach to implementing 2d terrain in Farseer. I'm going to assume you already have a reasonable grasp of xna and at least a basic grasp of Farseer, and that you either have access to an extensible map editor, you can build one, or that you're happy to create the coords for your terrain in some other way (perhaps in ASCII in a text file, or hard coded values).

However you get your data, for this tutorial you'll need to get it in the following format:

• Your terrain will need to be divided up into 'ledges', or continuous solid lines.

• Your ledges will need to be divided up into 'edges', a straight line between 2 'nodes'. The end node of one edge must be the beginning node of the next.

• Each ledge must be stored as a List of Vector2, each containing the coordinates in screenspace of the nodes (in the order they appear from one end of the ledge to the other).

Obviously you can adapt this, (array instead of list, Point instead of Vector2 etc) but for now I'll assume we are using the above.

We can now plug into the following method:


public CreatePhysicsLedge(List<Vector2> vectors, float friction, float restitution)
{
    body = BodyFactory.CreateBody(game.world);
    body.BodyType = BodyType.Static;
    body.IsStatic = true;
                
    fixtures = new List<Fixture>();

    for (int i = 1; i < vectors.Count; i++)
    {
        Vector2 tempVec1 = ConvertUnits.ToSimUnits(vectors[i - 1]);
        Vector2 tempVec2 = ConvertUnits.ToSimUnits(vectors[i]);
        EdgeShape shape = new EdgeShape(tempVec1, tempVec2);
        if (i != vectors.Count - 1)
        {
            shape.HasVertex3 = true;
            shape.Vertex3 = ConvertUnits.ToSimUnits(vectors[i + 1]);
        }
        if (i != 1)
        {
            shape.HasVertex0 = true;
            shape.Vertex0 = ConvertUnits.ToSimUnits(vectors[i - 2]);
        }
        fixtures.Add(body.CreateFixture(shape));
    }
    for (int i = 0; i < fixtures.Count; i++)
    {
        fixtures[i].Friction = friction;
        fixtures[i].Restitution = restitution;
    }
}

This makes use of the ConvertUnits class from the Farseer samples.

And that's it! Simple as that.

Hopefully that will save some other devs some time here or there. Enjoy!

No comments:

Post a Comment