Ragdoll.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. using FarseerPhysics.Common;
  2. using FarseerPhysics.Dynamics;
  3. using FarseerPhysics.Dynamics.Joints;
  4. using FarseerPhysics.Factories;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Graphics;
  7. namespace FarseerPhysics.SamplesFramework
  8. {
  9. public class Ragdoll
  10. {
  11. private const float ArmDensity = 10;
  12. private const float LegDensity = 15;
  13. private const float LimbAngularDamping = 7;
  14. private Body _body;
  15. private Sprite _face;
  16. private Body _head;
  17. private Sprite _lowerArm;
  18. private Body _lowerLeftArm;
  19. private Body _lowerLeftLeg;
  20. private Sprite _lowerLeg;
  21. private Body _lowerRightArm;
  22. private Body _lowerRightLeg;
  23. private PhysicsGameScreen _screen;
  24. private Sprite _torso;
  25. private Sprite _upperArm;
  26. private Body _upperLeftArm;
  27. private Body _upperLeftLeg;
  28. private Sprite _upperLeg;
  29. private Body _upperRightArm;
  30. private Body _upperRightLeg;
  31. public Ragdoll(World world, PhysicsGameScreen screen, Vector2 position)
  32. {
  33. CreateBody(world, position);
  34. CreateJoints(world);
  35. _screen = screen;
  36. CreateGFX();
  37. }
  38. public Body Body
  39. {
  40. get { return _body; }
  41. }
  42. //Torso
  43. private void CreateBody(World world, Vector2 position)
  44. {
  45. //Head
  46. _head = BodyFactory.CreateCircle(world, 0.9f, 10f);
  47. _head.BodyType = BodyType.Dynamic;
  48. _head.AngularDamping = LimbAngularDamping;
  49. _head.Mass = 2f;
  50. _head.Position = position;
  51. //Body
  52. _body = BodyFactory.CreateRoundedRectangle(world, 2f, 4f, 0.5f, 0.7f, 2, 10f);
  53. _body.BodyType = BodyType.Dynamic;
  54. _body.Mass = 2f;
  55. _body.Position = position + new Vector2(0f, 3f);
  56. //Left Arm
  57. _lowerLeftArm = BodyFactory.CreateCapsule(world, 1f, 0.45f, ArmDensity);
  58. _lowerLeftArm.BodyType = BodyType.Dynamic;
  59. _lowerLeftArm.AngularDamping = LimbAngularDamping;
  60. _lowerLeftArm.Mass = 2f;
  61. _lowerLeftArm.Rotation = 1.4f;
  62. _lowerLeftArm.Position = position + new Vector2(-4f, 2.2f);
  63. _upperLeftArm = BodyFactory.CreateCapsule(world, 1f, 0.45f, ArmDensity);
  64. _upperLeftArm.BodyType = BodyType.Dynamic;
  65. _upperLeftArm.AngularDamping = LimbAngularDamping;
  66. _upperLeftArm.Mass = 2f;
  67. _upperLeftArm.Rotation = 1.4f;
  68. _upperLeftArm.Position = position + new Vector2(-2f, 1.8f);
  69. //Right Arm
  70. _lowerRightArm = BodyFactory.CreateCapsule(world, 1f, 0.45f, ArmDensity);
  71. _lowerRightArm.BodyType = BodyType.Dynamic;
  72. _lowerRightArm.AngularDamping = LimbAngularDamping;
  73. _lowerRightArm.Mass = 2f;
  74. _lowerRightArm.Rotation = -1.4f;
  75. _lowerRightArm.Position = position + new Vector2(4f, 2.2f);
  76. _upperRightArm = BodyFactory.CreateCapsule(world, 1f, 0.45f, ArmDensity);
  77. _upperRightArm.BodyType = BodyType.Dynamic;
  78. _upperRightArm.AngularDamping = LimbAngularDamping;
  79. _upperRightArm.Mass = 2f;
  80. _upperRightArm.Rotation = -1.4f;
  81. _upperRightArm.Position = position + new Vector2(2f, 1.8f);
  82. //Left Leg
  83. _lowerLeftLeg = BodyFactory.CreateCapsule(world, 1f, 0.5f, LegDensity);
  84. _lowerLeftLeg.BodyType = BodyType.Dynamic;
  85. _lowerLeftLeg.AngularDamping = LimbAngularDamping;
  86. _lowerLeftLeg.Mass = 2f;
  87. _lowerLeftLeg.Position = position + new Vector2(-0.6f, 8f);
  88. _upperLeftLeg = BodyFactory.CreateCapsule(world, 1f, 0.5f, LegDensity);
  89. _upperLeftLeg.BodyType = BodyType.Dynamic;
  90. _upperLeftLeg.AngularDamping = LimbAngularDamping;
  91. _upperLeftLeg.Mass = 2f;
  92. _upperLeftLeg.Position = position + new Vector2(-0.6f, 6f);
  93. //Right Leg
  94. _lowerRightLeg = BodyFactory.CreateCapsule(world, 1f, 0.5f, LegDensity);
  95. _lowerRightLeg.BodyType = BodyType.Dynamic;
  96. _lowerRightLeg.AngularDamping = LimbAngularDamping;
  97. _lowerRightLeg.Mass = 2f;
  98. _lowerRightLeg.Position = position + new Vector2(0.6f, 8f);
  99. _upperRightLeg = BodyFactory.CreateCapsule(world, 1f, 0.5f, LegDensity);
  100. _upperRightLeg.BodyType = BodyType.Dynamic;
  101. _upperRightLeg.AngularDamping = LimbAngularDamping;
  102. _upperRightLeg.Mass = 2f;
  103. _upperRightLeg.Position = position + new Vector2(0.6f, 6f);
  104. }
  105. private void CreateJoints(World world)
  106. {
  107. const float dampingRatio = 1f;
  108. const float frequency = 25f;
  109. //head -> body
  110. DistanceJoint jHeadBody = new DistanceJoint(_head, _body,
  111. new Vector2(0f, 1f),
  112. new Vector2(0f, -2f));
  113. jHeadBody.CollideConnected = true;
  114. jHeadBody.DampingRatio = dampingRatio;
  115. jHeadBody.Frequency = frequency;
  116. jHeadBody.Length = 0.025f;
  117. world.AddJoint(jHeadBody);
  118. //lowerLeftArm -> upperLeftArm
  119. DistanceJoint jLeftArm = new DistanceJoint(_lowerLeftArm, _upperLeftArm,
  120. new Vector2(0f, -1f),
  121. new Vector2(0f, 1f));
  122. jLeftArm.CollideConnected = true;
  123. jLeftArm.DampingRatio = dampingRatio;
  124. jLeftArm.Frequency = frequency;
  125. jLeftArm.Length = 0.02f;
  126. world.AddJoint(jLeftArm);
  127. //upperLeftArm -> body
  128. DistanceJoint jLeftArmBody = new DistanceJoint(_upperLeftArm, _body,
  129. new Vector2(0f, -1f),
  130. new Vector2(-1f, -1.5f));
  131. jLeftArmBody.CollideConnected = true;
  132. jLeftArmBody.DampingRatio = dampingRatio;
  133. jLeftArmBody.Frequency = frequency;
  134. jLeftArmBody.Length = 0.02f;
  135. world.AddJoint(jLeftArmBody);
  136. //lowerRightArm -> upperRightArm
  137. DistanceJoint jRightArm = new DistanceJoint(_lowerRightArm, _upperRightArm,
  138. new Vector2(0f, -1f),
  139. new Vector2(0f, 1f));
  140. jRightArm.CollideConnected = true;
  141. jRightArm.DampingRatio = dampingRatio;
  142. jRightArm.Frequency = frequency;
  143. jRightArm.Length = 0.02f;
  144. world.AddJoint(jRightArm);
  145. //upperRightArm -> body
  146. DistanceJoint jRightArmBody = new DistanceJoint(_upperRightArm, _body,
  147. new Vector2(0f, -1f),
  148. new Vector2(1f, -1.5f));
  149. jRightArmBody.CollideConnected = true;
  150. jRightArmBody.DampingRatio = dampingRatio;
  151. jRightArmBody.Frequency = 25;
  152. jRightArmBody.Length = 0.02f;
  153. world.AddJoint(jRightArmBody);
  154. //lowerLeftLeg -> upperLeftLeg
  155. DistanceJoint jLeftLeg = new DistanceJoint(_lowerLeftLeg, _upperLeftLeg,
  156. new Vector2(0f, -1.1f),
  157. new Vector2(0f, 1f));
  158. jLeftLeg.CollideConnected = true;
  159. jLeftLeg.DampingRatio = dampingRatio;
  160. jLeftLeg.Frequency = frequency;
  161. jLeftLeg.Length = 0.05f;
  162. world.AddJoint(jLeftLeg);
  163. //upperLeftLeg -> body
  164. DistanceJoint jLeftLegBody = new DistanceJoint(_upperLeftLeg, _body,
  165. new Vector2(0f, -1.1f),
  166. new Vector2(-0.8f, 1.9f));
  167. jLeftLegBody.CollideConnected = true;
  168. jLeftLegBody.DampingRatio = dampingRatio;
  169. jLeftLegBody.Frequency = frequency;
  170. jLeftLegBody.Length = 0.02f;
  171. world.AddJoint(jLeftLegBody);
  172. //lowerRightleg -> upperRightleg
  173. DistanceJoint jRightLeg = new DistanceJoint(_lowerRightLeg, _upperRightLeg,
  174. new Vector2(0f, -1.1f),
  175. new Vector2(0f, 1f));
  176. jRightLeg.CollideConnected = true;
  177. jRightLeg.DampingRatio = dampingRatio;
  178. jRightLeg.Frequency = frequency;
  179. jRightLeg.Length = 0.05f;
  180. world.AddJoint(jRightLeg);
  181. //upperRightleg -> body
  182. DistanceJoint jRightLegBody = new DistanceJoint(_upperRightLeg, _body,
  183. new Vector2(0f, -1.1f),
  184. new Vector2(0.8f, 1.9f));
  185. jRightLegBody.CollideConnected = true;
  186. jRightLegBody.DampingRatio = dampingRatio;
  187. jRightLegBody.Frequency = frequency;
  188. jRightLegBody.Length = 0.02f;
  189. world.AddJoint(jRightLegBody);
  190. }
  191. private void CreateGFX()
  192. {
  193. AssetCreator creator = _screen.ScreenManager.Assets;
  194. _face = new Sprite(creator.CircleTexture(0.9f, MaterialType.Squares, Color.Gray, 1f));
  195. _torso = new Sprite(creator.TextureFromVertices(PolygonTools.CreateRoundedRectangle(2f, 4f, 0.5f, 0.7f, 2),
  196. MaterialType.Squares, Color.LightSlateGray, 0.8f));
  197. _upperArm = new Sprite(creator.TextureFromVertices(PolygonTools.CreateCapsule(1.9f, 0.45f, 16),
  198. MaterialType.Squares, Color.DimGray, 0.8f));
  199. _lowerArm = new Sprite(creator.TextureFromVertices(PolygonTools.CreateCapsule(1.9f, 0.45f, 16),
  200. MaterialType.Squares, Color.DarkSlateGray, 0.8f));
  201. _upperLeg = new Sprite(creator.TextureFromVertices(PolygonTools.CreateCapsule(2f, 0.5f, 16),
  202. MaterialType.Squares, Color.DimGray, 0.8f));
  203. _lowerLeg = new Sprite(creator.TextureFromVertices(PolygonTools.CreateCapsule(2f, 0.5f, 16),
  204. MaterialType.Squares, Color.DarkSlateGray, 0.8f));
  205. }
  206. public void Draw()
  207. {
  208. SpriteBatch batch = _screen.ScreenManager.SpriteBatch;
  209. batch.Draw(_lowerLeg.Texture, ConvertUnits.ToDisplayUnits(_lowerLeftLeg.Position), null,
  210. Color.White, _lowerLeftLeg.Rotation, _lowerLeg.Origin, 1f, SpriteEffects.None, 0f);
  211. batch.Draw(_lowerLeg.Texture, ConvertUnits.ToDisplayUnits(_lowerRightLeg.Position), null,
  212. Color.White, _lowerRightLeg.Rotation, _lowerLeg.Origin, 1f, SpriteEffects.None, 0f);
  213. batch.Draw(_upperLeg.Texture, ConvertUnits.ToDisplayUnits(_upperLeftLeg.Position), null,
  214. Color.White, _upperLeftLeg.Rotation, _upperLeg.Origin, 1f, SpriteEffects.None, 0f);
  215. batch.Draw(_upperLeg.Texture, ConvertUnits.ToDisplayUnits(_upperRightLeg.Position), null,
  216. Color.White, _upperRightLeg.Rotation, _upperLeg.Origin, 1f, SpriteEffects.None, 0f);
  217. batch.Draw(_lowerArm.Texture, ConvertUnits.ToDisplayUnits(_lowerLeftArm.Position), null,
  218. Color.White, _lowerLeftArm.Rotation, _lowerArm.Origin, 1f, SpriteEffects.None, 0f);
  219. batch.Draw(_lowerArm.Texture, ConvertUnits.ToDisplayUnits(_lowerRightArm.Position), null,
  220. Color.White, _lowerRightArm.Rotation, _lowerArm.Origin, 1f, SpriteEffects.None, 0f);
  221. batch.Draw(_upperArm.Texture, ConvertUnits.ToDisplayUnits(_upperLeftArm.Position), null,
  222. Color.White, _upperLeftArm.Rotation, _upperArm.Origin, 1f, SpriteEffects.None, 0f);
  223. batch.Draw(_upperArm.Texture, ConvertUnits.ToDisplayUnits(_upperRightArm.Position), null,
  224. Color.White, _upperRightArm.Rotation, _upperArm.Origin, 1f, SpriteEffects.None, 0f);
  225. batch.Draw(_torso.Texture, ConvertUnits.ToDisplayUnits(_body.Position), null,
  226. Color.White, _body.Rotation, _torso.Origin, 1f, SpriteEffects.None, 0f);
  227. batch.Draw(_face.Texture, ConvertUnits.ToDisplayUnits(_head.Position), null,
  228. Color.White, _head.Rotation, _face.Origin, 1f, SpriteEffects.None, 0f);
  229. }
  230. }
  231. }