GameDemo1.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using FarseerPhysics.Collision.Shapes;
  5. using FarseerPhysics.Common;
  6. using FarseerPhysics.Dynamics;
  7. using FarseerPhysics.Dynamics.Joints;
  8. using FarseerPhysics.Factories;
  9. using Microsoft.Xna.Framework;
  10. using Microsoft.Xna.Framework.Graphics;
  11. using Microsoft.Xna.Framework.Input;
  12. namespace FarseerPhysics.SamplesFramework
  13. {
  14. internal class GameDemo1 : PhysicsGameScreen, IDemoScreen
  15. {
  16. private float _acceleration;
  17. private Body _board;
  18. private Sprite _box;
  19. private List<Body> _boxes;
  20. private Sprite _bridge;
  21. private List<Body> _bridgeSegments;
  22. private Body _car;
  23. private Sprite _carBody;
  24. private Body _ground;
  25. private float _hzBack;
  26. private float _hzFront;
  27. private float _maxSpeed;
  28. private float _scale;
  29. private LineJoint _springBack;
  30. private LineJoint _springFront;
  31. private Sprite _teeter;
  32. private Sprite _wheel;
  33. private Body _wheelBack;
  34. private Body _wheelFront;
  35. private float _zeta;
  36. #region IDemoScreen Members
  37. public string GetTitle()
  38. {
  39. return "Racing Car";
  40. }
  41. public string GetDetails()
  42. {
  43. StringBuilder sb = new StringBuilder();
  44. sb.AppendLine("TODO: Add sample description!");
  45. sb.AppendLine(string.Empty);
  46. sb.AppendLine("GamePad:");
  47. sb.AppendLine(" - Exit to menu: Back button");
  48. sb.AppendLine(string.Empty);
  49. sb.AppendLine("Keyboard:");
  50. sb.AppendLine(" - Exit to menu: Escape");
  51. return sb.ToString();
  52. }
  53. #endregion
  54. public override void LoadContent()
  55. {
  56. base.LoadContent();
  57. World.Gravity = new Vector2(0f, 10f);
  58. HasCursor = false;
  59. EnableCameraControl = true;
  60. HasVirtualStick = true;
  61. _hzFront = 8.5f;
  62. _hzBack = 5.0f;
  63. _zeta = 0.85f;
  64. _maxSpeed = 50.0f;
  65. #if WINDOWS_PHONE
  66. _scale = 2f / 3f;
  67. #else
  68. _scale = 1f;
  69. #endif
  70. // terrain
  71. _ground = new Body(World);
  72. {
  73. Vertices terrain = new Vertices();
  74. terrain.Add(new Vector2(-20f, -5f));
  75. terrain.Add(new Vector2(-20f, 0f));
  76. terrain.Add(new Vector2(20f, 0f));
  77. terrain.Add(new Vector2(25f, -0.25f));
  78. terrain.Add(new Vector2(30f, -1f));
  79. terrain.Add(new Vector2(35f, -4f));
  80. terrain.Add(new Vector2(40f, 0f));
  81. terrain.Add(new Vector2(45f, 0f));
  82. terrain.Add(new Vector2(50f, 1f));
  83. terrain.Add(new Vector2(55f, 2f));
  84. terrain.Add(new Vector2(60f, 2f));
  85. terrain.Add(new Vector2(65f, 1.25f));
  86. terrain.Add(new Vector2(70f, 0f));
  87. terrain.Add(new Vector2(75f, -0.3f));
  88. terrain.Add(new Vector2(80f, -1.5f));
  89. terrain.Add(new Vector2(85f, -3.5f));
  90. terrain.Add(new Vector2(90f, 0f));
  91. terrain.Add(new Vector2(95f, 0.5f));
  92. terrain.Add(new Vector2(100f, 1f));
  93. terrain.Add(new Vector2(105f, 2f));
  94. terrain.Add(new Vector2(110f, 2.5f));
  95. terrain.Add(new Vector2(115f, 1.3f));
  96. terrain.Add(new Vector2(120f, 0f));
  97. terrain.Add(new Vector2(160f, 0f));
  98. terrain.Add(new Vector2(159f, 10f));
  99. terrain.Add(new Vector2(201f, 10f));
  100. terrain.Add(new Vector2(200f, 0f));
  101. terrain.Add(new Vector2(240f, 0f));
  102. terrain.Add(new Vector2(250f, -5f));
  103. terrain.Add(new Vector2(250f, 10f));
  104. terrain.Add(new Vector2(270f, 10f));
  105. terrain.Add(new Vector2(270f, 0));
  106. terrain.Add(new Vector2(310f, 0));
  107. terrain.Add(new Vector2(310f, -5));
  108. for (int i = 0; i < terrain.Count - 1; ++i)
  109. {
  110. FixtureFactory.AttachEdge(terrain[i], terrain[i + 1], _ground);
  111. }
  112. _ground.Friction = 0.6f;
  113. }
  114. // teeter board
  115. {
  116. _board = new Body(World);
  117. _board.BodyType = BodyType.Dynamic;
  118. _board.Position = new Vector2(140.0f, -1.0f);
  119. PolygonShape box = new PolygonShape(1f);
  120. box.SetAsBox(10.0f, 0.25f);
  121. _teeter =
  122. new Sprite(ScreenManager.Assets.TextureFromShape(box, MaterialType.Pavement, Color.LightGray, 1.2f));
  123. _board.CreateFixture(box);
  124. RevoluteJoint teeterAxis = JointFactory.CreateRevoluteJoint(_ground, _board, Vector2.Zero);
  125. teeterAxis.LowerLimit = -8.0f * Settings.Pi / 180.0f;
  126. teeterAxis.UpperLimit = 8.0f * Settings.Pi / 180.0f;
  127. teeterAxis.LimitEnabled = true;
  128. World.AddJoint(teeterAxis);
  129. _board.ApplyAngularImpulse(-100.0f);
  130. }
  131. // bridge
  132. {
  133. _bridgeSegments = new List<Body>();
  134. const int segmentCount = 20;
  135. PolygonShape shape = new PolygonShape(1f);
  136. shape.SetAsBox(1.0f, 0.125f);
  137. _bridge =
  138. new Sprite(ScreenManager.Assets.TextureFromShape(shape, MaterialType.Dots, Color.SandyBrown, 1f));
  139. Body prevBody = _ground;
  140. for (int i = 0; i < segmentCount; ++i)
  141. {
  142. Body body = new Body(World);
  143. body.BodyType = BodyType.Dynamic;
  144. body.Position = new Vector2(161f + 2f * i, 0.125f);
  145. Fixture fix = body.CreateFixture(shape);
  146. fix.Friction = 0.6f;
  147. JointFactory.CreateRevoluteJoint(World, prevBody, body, -Vector2.UnitX);
  148. prevBody = body;
  149. _bridgeSegments.Add(body);
  150. }
  151. JointFactory.CreateRevoluteJoint(World, _ground, prevBody, Vector2.UnitX);
  152. }
  153. // boxes
  154. {
  155. _boxes = new List<Body>();
  156. PolygonShape box = new PolygonShape(1f);
  157. box.SetAsBox(0.5f, 0.5f);
  158. _box =
  159. new Sprite(ScreenManager.Assets.TextureFromShape(box, MaterialType.Squares, Color.SaddleBrown, 2f));
  160. Body body = new Body(World);
  161. body.BodyType = BodyType.Dynamic;
  162. body.Position = new Vector2(220f, -0.5f);
  163. body.CreateFixture(box);
  164. _boxes.Add(body);
  165. body = new Body(World);
  166. body.BodyType = BodyType.Dynamic;
  167. body.Position = new Vector2(220f, -1.5f);
  168. body.CreateFixture(box);
  169. _boxes.Add(body);
  170. body = new Body(World);
  171. body.BodyType = BodyType.Dynamic;
  172. body.Position = new Vector2(220f, -2.5f);
  173. body.CreateFixture(box);
  174. _boxes.Add(body);
  175. }
  176. // car
  177. {
  178. Vertices vertices = new Vertices(8);
  179. vertices.Add(new Vector2(-2.5f, 0.08f));
  180. vertices.Add(new Vector2(-2.375f, -0.46f));
  181. vertices.Add(new Vector2(-0.58f, -0.92f));
  182. vertices.Add(new Vector2(0.46f, -0.92f));
  183. vertices.Add(new Vector2(2.5f, -0.17f));
  184. vertices.Add(new Vector2(2.5f, 0.205f));
  185. vertices.Add(new Vector2(2.3f, 0.33f));
  186. vertices.Add(new Vector2(-2.25f, 0.35f));
  187. PolygonShape chassis = new PolygonShape(vertices, 2f);
  188. _car = new Body(World);
  189. _car.BodyType = BodyType.Dynamic;
  190. _car.Position = new Vector2(0.0f, -1.0f);
  191. _car.CreateFixture(chassis);
  192. _wheelBack = new Body(World);
  193. _wheelBack.BodyType = BodyType.Dynamic;
  194. _wheelBack.Position = new Vector2(-1.709f, -0.78f);
  195. Fixture fix = _wheelBack.CreateFixture(new CircleShape(0.5f, 0.8f));
  196. fix.Friction = 0.9f;
  197. _wheelFront = new Body(World);
  198. _wheelFront.BodyType = BodyType.Dynamic;
  199. _wheelFront.Position = new Vector2(1.54f, -0.8f);
  200. _wheelFront.CreateFixture(new CircleShape(0.5f, 1f));
  201. Vector2 axis = new Vector2(0.0f, -1.2f);
  202. _springBack = new LineJoint(_car, _wheelBack, _wheelBack.Position, axis);
  203. _springBack.MotorSpeed = 0.0f;
  204. _springBack.MaxMotorTorque = 20.0f;
  205. _springBack.MotorEnabled = true;
  206. _springBack.Frequency = _hzBack;
  207. _springBack.DampingRatio = _zeta;
  208. World.AddJoint(_springBack);
  209. _springFront = new LineJoint(_car, _wheelFront, _wheelFront.Position, axis);
  210. _springFront.MotorSpeed = 0.0f;
  211. _springFront.MaxMotorTorque = 10.0f;
  212. _springFront.MotorEnabled = false;
  213. _springFront.Frequency = _hzFront;
  214. _springFront.DampingRatio = _zeta;
  215. World.AddJoint(_springFront);
  216. _carBody = new Sprite(ScreenManager.Content.Load<Texture2D>("Samples/car"),
  217. AssetCreator.CalculateOrigin(_car) / _scale);
  218. _wheel = new Sprite(ScreenManager.Content.Load<Texture2D>("Samples/wheel"));
  219. }
  220. Camera.MinRotation = -0.05f;
  221. Camera.MaxRotation = 0.05f;
  222. Camera.TrackingBody = _car;
  223. Camera.EnableTracking = true;
  224. }
  225. public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
  226. {
  227. _springBack.MotorSpeed = Math.Sign(_acceleration) *
  228. MathHelper.SmoothStep(0f, _maxSpeed, Math.Abs(_acceleration));
  229. if (Math.Abs(_springBack.MotorSpeed) < _maxSpeed * 0.06f)
  230. {
  231. _springBack.MotorEnabled = false;
  232. }
  233. else
  234. {
  235. _springBack.MotorEnabled = true;
  236. }
  237. base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
  238. }
  239. public override void HandleInput(InputHelper input, GameTime gameTime)
  240. {
  241. if (input.VirtualState.ThumbSticks.Left.X > 0.5f)
  242. {
  243. _acceleration = Math.Min(_acceleration + (float)(2.0 * gameTime.ElapsedGameTime.TotalSeconds), 1f);
  244. }
  245. else if (input.VirtualState.ThumbSticks.Left.X < -0.5f)
  246. {
  247. _acceleration = Math.Max(_acceleration - (float)(2.0 * gameTime.ElapsedGameTime.TotalSeconds), -1f);
  248. }
  249. else if (input.VirtualState.Buttons.A == ButtonState.Pressed)
  250. {
  251. _acceleration = 0f;
  252. }
  253. else
  254. {
  255. _acceleration -= Math.Sign(_acceleration) * (float)(2.0 * gameTime.ElapsedGameTime.TotalSeconds);
  256. }
  257. base.HandleInput(input, gameTime);
  258. }
  259. public override void Draw(GameTime gameTime)
  260. {
  261. ScreenManager.SpriteBatch.Begin(0, null, null, null, null, null, Camera.View);
  262. // draw car
  263. ScreenManager.SpriteBatch.Draw(_wheel.Texture, ConvertUnits.ToDisplayUnits(_wheelBack.Position), null,
  264. Color.White, _wheelBack.Rotation, _wheel.Origin, _scale, SpriteEffects.None,
  265. 0f);
  266. ScreenManager.SpriteBatch.Draw(_wheel.Texture, ConvertUnits.ToDisplayUnits(_wheelFront.Position), null,
  267. Color.White, _wheelFront.Rotation, _wheel.Origin, _scale, SpriteEffects.None,
  268. 0f);
  269. ScreenManager.SpriteBatch.Draw(_carBody.Texture, ConvertUnits.ToDisplayUnits(_car.Position), null,
  270. Color.White, _car.Rotation, _carBody.Origin, _scale, SpriteEffects.None, 0f);
  271. // draw teeter
  272. ScreenManager.SpriteBatch.Draw(_teeter.Texture, ConvertUnits.ToDisplayUnits(_board.Position), null,
  273. Color.White, _board.Rotation, _teeter.Origin, 1f, SpriteEffects.None, 0f);
  274. // draw bridge
  275. for (int i = 0; i < _bridgeSegments.Count; ++i)
  276. {
  277. ScreenManager.SpriteBatch.Draw(_bridge.Texture, ConvertUnits.ToDisplayUnits(_bridgeSegments[i].Position),
  278. null,
  279. Color.White, _bridgeSegments[i].Rotation, _bridge.Origin, 1f,
  280. SpriteEffects.None, 0f);
  281. }
  282. // draw boxes
  283. for (int i = 0; i < _boxes.Count; ++i)
  284. {
  285. ScreenManager.SpriteBatch.Draw(_box.Texture, ConvertUnits.ToDisplayUnits(_boxes[i].Position), null,
  286. Color.White, _boxes[i].Rotation, _box.Origin, 1f, SpriteEffects.None, 0f);
  287. }
  288. ScreenManager.SpriteBatch.End();
  289. ScreenManager.LineBatch.Begin(Camera.SimProjection, Camera.SimView);
  290. // draw ground
  291. for (int i = 0; i < _ground.FixtureList.Count; ++i)
  292. {
  293. ScreenManager.LineBatch.DrawLineShape(_ground.FixtureList[i].Shape, Color.Black);
  294. }
  295. ScreenManager.LineBatch.End();
  296. base.Draw(gameTime);
  297. }
  298. }
  299. }