using FarseerPhysics.Common; using FarseerPhysics.Dynamics; using FarseerPhysics.Dynamics.Joints; using FarseerPhysics.Factories; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace FarseerPhysics.SamplesFramework { public class Ragdoll { private const float ArmDensity = 10; private const float LegDensity = 15; private const float LimbAngularDamping = 7; private Body _body; private Sprite _face; private Body _head; private Sprite _lowerArm; private Body _lowerLeftArm; private Body _lowerLeftLeg; private Sprite _lowerLeg; private Body _lowerRightArm; private Body _lowerRightLeg; private PhysicsGameScreen _screen; private Sprite _torso; private Sprite _upperArm; private Body _upperLeftArm; private Body _upperLeftLeg; private Sprite _upperLeg; private Body _upperRightArm; private Body _upperRightLeg; public Ragdoll(World world, PhysicsGameScreen screen, Vector2 position) { CreateBody(world, position); CreateJoints(world); _screen = screen; CreateGFX(); } public Body Body { get { return _body; } } //Torso private void CreateBody(World world, Vector2 position) { //Head _head = BodyFactory.CreateCircle(world, 0.9f, 10f); _head.BodyType = BodyType.Dynamic; _head.AngularDamping = LimbAngularDamping; _head.Mass = 2f; _head.Position = position; //Body _body = BodyFactory.CreateRoundedRectangle(world, 2f, 4f, 0.5f, 0.7f, 2, 10f); _body.BodyType = BodyType.Dynamic; _body.Mass = 2f; _body.Position = position + new Vector2(0f, 3f); //Left Arm _lowerLeftArm = BodyFactory.CreateCapsule(world, 1f, 0.45f, ArmDensity); _lowerLeftArm.BodyType = BodyType.Dynamic; _lowerLeftArm.AngularDamping = LimbAngularDamping; _lowerLeftArm.Mass = 2f; _lowerLeftArm.Rotation = 1.4f; _lowerLeftArm.Position = position + new Vector2(-4f, 2.2f); _upperLeftArm = BodyFactory.CreateCapsule(world, 1f, 0.45f, ArmDensity); _upperLeftArm.BodyType = BodyType.Dynamic; _upperLeftArm.AngularDamping = LimbAngularDamping; _upperLeftArm.Mass = 2f; _upperLeftArm.Rotation = 1.4f; _upperLeftArm.Position = position + new Vector2(-2f, 1.8f); //Right Arm _lowerRightArm = BodyFactory.CreateCapsule(world, 1f, 0.45f, ArmDensity); _lowerRightArm.BodyType = BodyType.Dynamic; _lowerRightArm.AngularDamping = LimbAngularDamping; _lowerRightArm.Mass = 2f; _lowerRightArm.Rotation = -1.4f; _lowerRightArm.Position = position + new Vector2(4f, 2.2f); _upperRightArm = BodyFactory.CreateCapsule(world, 1f, 0.45f, ArmDensity); _upperRightArm.BodyType = BodyType.Dynamic; _upperRightArm.AngularDamping = LimbAngularDamping; _upperRightArm.Mass = 2f; _upperRightArm.Rotation = -1.4f; _upperRightArm.Position = position + new Vector2(2f, 1.8f); //Left Leg _lowerLeftLeg = BodyFactory.CreateCapsule(world, 1f, 0.5f, LegDensity); _lowerLeftLeg.BodyType = BodyType.Dynamic; _lowerLeftLeg.AngularDamping = LimbAngularDamping; _lowerLeftLeg.Mass = 2f; _lowerLeftLeg.Position = position + new Vector2(-0.6f, 8f); _upperLeftLeg = BodyFactory.CreateCapsule(world, 1f, 0.5f, LegDensity); _upperLeftLeg.BodyType = BodyType.Dynamic; _upperLeftLeg.AngularDamping = LimbAngularDamping; _upperLeftLeg.Mass = 2f; _upperLeftLeg.Position = position + new Vector2(-0.6f, 6f); //Right Leg _lowerRightLeg = BodyFactory.CreateCapsule(world, 1f, 0.5f, LegDensity); _lowerRightLeg.BodyType = BodyType.Dynamic; _lowerRightLeg.AngularDamping = LimbAngularDamping; _lowerRightLeg.Mass = 2f; _lowerRightLeg.Position = position + new Vector2(0.6f, 8f); _upperRightLeg = BodyFactory.CreateCapsule(world, 1f, 0.5f, LegDensity); _upperRightLeg.BodyType = BodyType.Dynamic; _upperRightLeg.AngularDamping = LimbAngularDamping; _upperRightLeg.Mass = 2f; _upperRightLeg.Position = position + new Vector2(0.6f, 6f); } private void CreateJoints(World world) { const float dampingRatio = 1f; const float frequency = 25f; //head -> body DistanceJoint jHeadBody = new DistanceJoint(_head, _body, new Vector2(0f, 1f), new Vector2(0f, -2f)); jHeadBody.CollideConnected = true; jHeadBody.DampingRatio = dampingRatio; jHeadBody.Frequency = frequency; jHeadBody.Length = 0.025f; world.AddJoint(jHeadBody); //lowerLeftArm -> upperLeftArm DistanceJoint jLeftArm = new DistanceJoint(_lowerLeftArm, _upperLeftArm, new Vector2(0f, -1f), new Vector2(0f, 1f)); jLeftArm.CollideConnected = true; jLeftArm.DampingRatio = dampingRatio; jLeftArm.Frequency = frequency; jLeftArm.Length = 0.02f; world.AddJoint(jLeftArm); //upperLeftArm -> body DistanceJoint jLeftArmBody = new DistanceJoint(_upperLeftArm, _body, new Vector2(0f, -1f), new Vector2(-1f, -1.5f)); jLeftArmBody.CollideConnected = true; jLeftArmBody.DampingRatio = dampingRatio; jLeftArmBody.Frequency = frequency; jLeftArmBody.Length = 0.02f; world.AddJoint(jLeftArmBody); //lowerRightArm -> upperRightArm DistanceJoint jRightArm = new DistanceJoint(_lowerRightArm, _upperRightArm, new Vector2(0f, -1f), new Vector2(0f, 1f)); jRightArm.CollideConnected = true; jRightArm.DampingRatio = dampingRatio; jRightArm.Frequency = frequency; jRightArm.Length = 0.02f; world.AddJoint(jRightArm); //upperRightArm -> body DistanceJoint jRightArmBody = new DistanceJoint(_upperRightArm, _body, new Vector2(0f, -1f), new Vector2(1f, -1.5f)); jRightArmBody.CollideConnected = true; jRightArmBody.DampingRatio = dampingRatio; jRightArmBody.Frequency = 25; jRightArmBody.Length = 0.02f; world.AddJoint(jRightArmBody); //lowerLeftLeg -> upperLeftLeg DistanceJoint jLeftLeg = new DistanceJoint(_lowerLeftLeg, _upperLeftLeg, new Vector2(0f, -1.1f), new Vector2(0f, 1f)); jLeftLeg.CollideConnected = true; jLeftLeg.DampingRatio = dampingRatio; jLeftLeg.Frequency = frequency; jLeftLeg.Length = 0.05f; world.AddJoint(jLeftLeg); //upperLeftLeg -> body DistanceJoint jLeftLegBody = new DistanceJoint(_upperLeftLeg, _body, new Vector2(0f, -1.1f), new Vector2(-0.8f, 1.9f)); jLeftLegBody.CollideConnected = true; jLeftLegBody.DampingRatio = dampingRatio; jLeftLegBody.Frequency = frequency; jLeftLegBody.Length = 0.02f; world.AddJoint(jLeftLegBody); //lowerRightleg -> upperRightleg DistanceJoint jRightLeg = new DistanceJoint(_lowerRightLeg, _upperRightLeg, new Vector2(0f, -1.1f), new Vector2(0f, 1f)); jRightLeg.CollideConnected = true; jRightLeg.DampingRatio = dampingRatio; jRightLeg.Frequency = frequency; jRightLeg.Length = 0.05f; world.AddJoint(jRightLeg); //upperRightleg -> body DistanceJoint jRightLegBody = new DistanceJoint(_upperRightLeg, _body, new Vector2(0f, -1.1f), new Vector2(0.8f, 1.9f)); jRightLegBody.CollideConnected = true; jRightLegBody.DampingRatio = dampingRatio; jRightLegBody.Frequency = frequency; jRightLegBody.Length = 0.02f; world.AddJoint(jRightLegBody); } private void CreateGFX() { AssetCreator creator = _screen.ScreenManager.Assets; _face = new Sprite(creator.CircleTexture(0.9f, MaterialType.Squares, Color.Gray, 1f)); _torso = new Sprite(creator.TextureFromVertices(PolygonTools.CreateRoundedRectangle(2f, 4f, 0.5f, 0.7f, 2), MaterialType.Squares, Color.LightSlateGray, 0.8f)); _upperArm = new Sprite(creator.TextureFromVertices(PolygonTools.CreateCapsule(1.9f, 0.45f, 16), MaterialType.Squares, Color.DimGray, 0.8f)); _lowerArm = new Sprite(creator.TextureFromVertices(PolygonTools.CreateCapsule(1.9f, 0.45f, 16), MaterialType.Squares, Color.DarkSlateGray, 0.8f)); _upperLeg = new Sprite(creator.TextureFromVertices(PolygonTools.CreateCapsule(2f, 0.5f, 16), MaterialType.Squares, Color.DimGray, 0.8f)); _lowerLeg = new Sprite(creator.TextureFromVertices(PolygonTools.CreateCapsule(2f, 0.5f, 16), MaterialType.Squares, Color.DarkSlateGray, 0.8f)); } public void Draw() { SpriteBatch batch = _screen.ScreenManager.SpriteBatch; batch.Draw(_lowerLeg.Texture, ConvertUnits.ToDisplayUnits(_lowerLeftLeg.Position), null, Color.White, _lowerLeftLeg.Rotation, _lowerLeg.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_lowerLeg.Texture, ConvertUnits.ToDisplayUnits(_lowerRightLeg.Position), null, Color.White, _lowerRightLeg.Rotation, _lowerLeg.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_upperLeg.Texture, ConvertUnits.ToDisplayUnits(_upperLeftLeg.Position), null, Color.White, _upperLeftLeg.Rotation, _upperLeg.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_upperLeg.Texture, ConvertUnits.ToDisplayUnits(_upperRightLeg.Position), null, Color.White, _upperRightLeg.Rotation, _upperLeg.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_lowerArm.Texture, ConvertUnits.ToDisplayUnits(_lowerLeftArm.Position), null, Color.White, _lowerLeftArm.Rotation, _lowerArm.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_lowerArm.Texture, ConvertUnits.ToDisplayUnits(_lowerRightArm.Position), null, Color.White, _lowerRightArm.Rotation, _lowerArm.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_upperArm.Texture, ConvertUnits.ToDisplayUnits(_upperLeftArm.Position), null, Color.White, _upperLeftArm.Rotation, _upperArm.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_upperArm.Texture, ConvertUnits.ToDisplayUnits(_upperRightArm.Position), null, Color.White, _upperRightArm.Rotation, _upperArm.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_torso.Texture, ConvertUnits.ToDisplayUnits(_body.Position), null, Color.White, _body.Rotation, _torso.Origin, 1f, SpriteEffects.None, 0f); batch.Draw(_face.Texture, ConvertUnits.ToDisplayUnits(_head.Position), null, Color.White, _head.Rotation, _face.Origin, 1f, SpriteEffects.None, 0f); } } }