I am working on a 2D side-scroller using Farseer Physics Engine v3.3.1.
In order to create a realistic physical skeleton for the player, I am using a method similar to the one explained here (See "Texture to polygon" section).
Below is my code for creating the player body:
uint[] data = new uint[Source.Width * Source.Height];
mTexture.GetData(0, Source, data, 0, Source.Width * Source.Height);
Vertices textureVertices = PolygonTools.CreatePolygon(data, Source.Width, false);
Vector2 centroid = -textureVertices.GetCentroid();
textureVertices.Translate(ref centroid);
mPhysicalDrawOrigin = -centroid;
textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 2.5f);
List<Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices);
Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * Scale;
foreach (Vertices vertices in list)
{
vertices.Scale(ref vertScale);
}
mBody = BodyFactory.CreateCompoundPolygon(mWorld, list, 1f, BodyType.Dynamic);
The player's sprite is animated, though, so the problem arises when switching states - I.e. the player is crouching or jumping. The physical body created above only reflects one state (currently standing).
Is there a way I could somehow create a body for each sprite and swap them out later?
UPDATE:
As suggested by @Nick Wiggill, I am creating one physical body per player state (I.e. walking, standing, jumping, etc) when the player is loaded, and saving them within my class. All the bodies have .Enabled = false; initially, and are only enabled when the player is in the state that corresponds to that physical body. The Bodies and their corresponding states are stored in parallel lists.
Currently, my class has a function SetState which takes care of changing the physical body when the state is changed:
new protected void SetState(object nState)
{
//If mBody == null, the player is being loaded for the first time
if (mBody == null)
{
mBody = mBodies[mStates.IndexOf(nState)];
mBody.Enabled = true;
}
else
{
//Get the body for the given state
Body nBody = mBodies[mStates.IndexOf(nState)];
//Disable the current body
mBody.Enabled = false;
//Copy the current body's attributes to the new one
nBody.Position = mBody.Position;
nBody.LinearVelocity = mBody.LinearVelocity;
nBody.AngularVelocity = mBody.AngularVelocity;
//Set the current body to the new body
mBody = nBody;
//Enable the new body
nBody.Enabled = true;
}
}
Currently, when the game loads, a NullReferenceException is thrown when calling World.Step:
mWorld.Step(Math.Min((float)nGameTime.ElapsedGameTime.TotalSeconds, (1f / 30f)));
In the above function, mBody is just a variable I have to keep track of the current active body. I'm not modifying the body in any other way outside of the above function, and none of the m* variables are referenced or saved anywhere outside of my class. Perhaps I am swapping the bodies incorrectly?
UPDATE: Created a new question with the newer, slightly more specific issue: Farseer Physics - IndexOutOfRangeException when calling World.Step after Enabling/Disabling a body
