PhysicsGameScreen.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. using System;
  2. using FarseerPhysics.DebugViews;
  3. using FarseerPhysics.Dynamics;
  4. using FarseerPhysics.Dynamics.Joints;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Input;
  7. namespace FarseerPhysics.SamplesFramework
  8. {
  9. public class PhysicsGameScreen : GameScreen
  10. {
  11. public Camera2D Camera;
  12. protected DebugViewXNA DebugView;
  13. protected World World;
  14. private float _agentForce;
  15. private float _agentTorque;
  16. private FixedMouseJoint _fixedMouseJoint;
  17. private Body _userAgent;
  18. protected PhysicsGameScreen()
  19. {
  20. TransitionOnTime = TimeSpan.FromSeconds(0.75);
  21. TransitionOffTime = TimeSpan.FromSeconds(0.75);
  22. HasCursor = true;
  23. EnableCameraControl = true;
  24. _userAgent = null;
  25. World = null;
  26. Camera = null;
  27. DebugView = null;
  28. }
  29. public bool EnableCameraControl { get; set; }
  30. protected void SetUserAgent(Body agent, float force, float torque)
  31. {
  32. _userAgent = agent;
  33. _agentForce = force;
  34. _agentTorque = torque;
  35. }
  36. public override void LoadContent()
  37. {
  38. base.LoadContent();
  39. //We enable diagnostics to show get values for our performance counters.
  40. Settings.EnableDiagnostics = true;
  41. if (World == null)
  42. {
  43. World = new World(Vector2.Zero);
  44. }
  45. else
  46. {
  47. World.Clear();
  48. }
  49. if (DebugView == null)
  50. {
  51. DebugView = new DebugViewXNA(World);
  52. DebugView.RemoveFlags(DebugViewFlags.Shape);
  53. DebugView.RemoveFlags(DebugViewFlags.Joint);
  54. DebugView.DefaultShapeColor = Color.White;
  55. DebugView.SleepingShapeColor = Color.LightGray;
  56. DebugView.LoadContent(ScreenManager.GraphicsDevice, ScreenManager.Content);
  57. }
  58. if (Camera == null)
  59. {
  60. Camera = new Camera2D(ScreenManager.GraphicsDevice);
  61. }
  62. else
  63. {
  64. Camera.ResetCamera();
  65. }
  66. // Loading may take a while... so prevent the game from "catching up" once we finished loading
  67. ScreenManager.Game.ResetElapsedTime();
  68. }
  69. public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
  70. {
  71. if (!coveredByOtherScreen && !otherScreenHasFocus)
  72. {
  73. // variable time step but never less then 30 Hz
  74. World.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalSeconds, (1f / 30f)));
  75. }
  76. else
  77. {
  78. World.Step(0f);
  79. }
  80. Camera.Update(gameTime);
  81. base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
  82. }
  83. public override void HandleInput(InputHelper input, GameTime gameTime)
  84. {
  85. // Control debug view
  86. if (input.IsNewButtonPress(Buttons.Start))
  87. {
  88. EnableOrDisableFlag(DebugViewFlags.Shape);
  89. EnableOrDisableFlag(DebugViewFlags.DebugPanel);
  90. EnableOrDisableFlag(DebugViewFlags.PerformanceGraph);
  91. EnableOrDisableFlag(DebugViewFlags.Joint);
  92. EnableOrDisableFlag(DebugViewFlags.ContactPoints);
  93. EnableOrDisableFlag(DebugViewFlags.ContactNormals);
  94. EnableOrDisableFlag(DebugViewFlags.Controllers);
  95. }
  96. if (input.IsNewKeyPress(Keys.F1))
  97. {
  98. EnableOrDisableFlag(DebugViewFlags.Shape);
  99. }
  100. if (input.IsNewKeyPress(Keys.F2))
  101. {
  102. EnableOrDisableFlag(DebugViewFlags.DebugPanel);
  103. EnableOrDisableFlag(DebugViewFlags.PerformanceGraph);
  104. }
  105. if (input.IsNewKeyPress(Keys.F3))
  106. {
  107. EnableOrDisableFlag(DebugViewFlags.Joint);
  108. }
  109. if (input.IsNewKeyPress(Keys.F4))
  110. {
  111. EnableOrDisableFlag(DebugViewFlags.ContactPoints);
  112. EnableOrDisableFlag(DebugViewFlags.ContactNormals);
  113. }
  114. if (input.IsNewKeyPress(Keys.F5))
  115. {
  116. EnableOrDisableFlag(DebugViewFlags.PolygonPoints);
  117. }
  118. if (input.IsNewKeyPress(Keys.F6))
  119. {
  120. EnableOrDisableFlag(DebugViewFlags.Controllers);
  121. }
  122. if (input.IsNewKeyPress(Keys.F7))
  123. {
  124. EnableOrDisableFlag(DebugViewFlags.CenterOfMass);
  125. }
  126. if (input.IsNewKeyPress(Keys.F8))
  127. {
  128. EnableOrDisableFlag(DebugViewFlags.AABB);
  129. }
  130. if (input.IsNewButtonPress(Buttons.Back) || input.IsNewKeyPress(Keys.Escape))
  131. {
  132. ExitScreen();
  133. }
  134. if (HasCursor)
  135. {
  136. HandleCursor(input);
  137. }
  138. if (_userAgent != null)
  139. {
  140. HandleUserAgent(input);
  141. }
  142. if (EnableCameraControl)
  143. {
  144. HandleCamera(input, gameTime);
  145. }
  146. base.HandleInput(input, gameTime);
  147. }
  148. private void HandleCursor(InputHelper input)
  149. {
  150. Vector2 position = Camera.ConvertScreenToWorld(input.Cursor);
  151. if ((input.IsNewButtonPress(Buttons.A) ||
  152. input.IsNewMouseButtonPress(MouseButtons.LeftButton)) &&
  153. _fixedMouseJoint == null)
  154. {
  155. Fixture savedFixture = World.TestPoint(position);
  156. if (savedFixture != null)
  157. {
  158. Body body = savedFixture.Body;
  159. _fixedMouseJoint = new FixedMouseJoint(body, position);
  160. _fixedMouseJoint.MaxForce = 1000.0f * body.Mass;
  161. World.AddJoint(_fixedMouseJoint);
  162. body.Awake = true;
  163. }
  164. }
  165. if ((input.IsNewButtonRelease(Buttons.A) ||
  166. input.IsNewMouseButtonRelease(MouseButtons.LeftButton)) &&
  167. _fixedMouseJoint != null)
  168. {
  169. World.RemoveJoint(_fixedMouseJoint);
  170. _fixedMouseJoint = null;
  171. }
  172. if (_fixedMouseJoint != null)
  173. {
  174. _fixedMouseJoint.WorldAnchorB = position;
  175. }
  176. }
  177. private void HandleCamera(InputHelper input, GameTime gameTime)
  178. {
  179. Vector2 camMove = Vector2.Zero;
  180. if (input.KeyboardState.IsKeyDown(Keys.Up))
  181. {
  182. camMove.Y -= 10f * (float)gameTime.ElapsedGameTime.TotalSeconds;
  183. }
  184. if (input.KeyboardState.IsKeyDown(Keys.Down))
  185. {
  186. camMove.Y += 10f * (float)gameTime.ElapsedGameTime.TotalSeconds;
  187. }
  188. if (input.KeyboardState.IsKeyDown(Keys.Left))
  189. {
  190. camMove.X -= 10f * (float)gameTime.ElapsedGameTime.TotalSeconds;
  191. }
  192. if (input.KeyboardState.IsKeyDown(Keys.Right))
  193. {
  194. camMove.X += 10f * (float)gameTime.ElapsedGameTime.TotalSeconds;
  195. }
  196. if (input.KeyboardState.IsKeyDown(Keys.PageUp))
  197. {
  198. Camera.Zoom += 5f * (float)gameTime.ElapsedGameTime.TotalSeconds * Camera.Zoom / 20f;
  199. }
  200. if (input.KeyboardState.IsKeyDown(Keys.PageDown))
  201. {
  202. Camera.Zoom -= 5f * (float)gameTime.ElapsedGameTime.TotalSeconds * Camera.Zoom / 20f;
  203. }
  204. if (camMove != Vector2.Zero)
  205. {
  206. Camera.MoveCamera(camMove);
  207. }
  208. if (input.IsNewKeyPress(Keys.Home))
  209. {
  210. Camera.ResetCamera();
  211. }
  212. }
  213. private void HandleUserAgent(InputHelper input)
  214. {
  215. Vector2 force = _agentForce * new Vector2(input.GamePadState.ThumbSticks.Right.X,
  216. -input.GamePadState.ThumbSticks.Right.Y);
  217. float torque = _agentTorque * (input.GamePadState.Triggers.Right - input.GamePadState.Triggers.Left);
  218. _userAgent.ApplyForce(force);
  219. _userAgent.ApplyTorque(torque);
  220. float forceAmount = _agentForce * 0.6f;
  221. force = Vector2.Zero;
  222. torque = 0;
  223. if (input.KeyboardState.IsKeyDown(Keys.A))
  224. {
  225. force += new Vector2(-forceAmount, 0);
  226. }
  227. if (input.KeyboardState.IsKeyDown(Keys.S))
  228. {
  229. force += new Vector2(0, forceAmount);
  230. }
  231. if (input.KeyboardState.IsKeyDown(Keys.D))
  232. {
  233. force += new Vector2(forceAmount, 0);
  234. }
  235. if (input.KeyboardState.IsKeyDown(Keys.W))
  236. {
  237. force += new Vector2(0, -forceAmount);
  238. }
  239. if (input.KeyboardState.IsKeyDown(Keys.Q))
  240. {
  241. torque -= _agentTorque;
  242. }
  243. if (input.KeyboardState.IsKeyDown(Keys.E))
  244. {
  245. torque += _agentTorque;
  246. }
  247. _userAgent.ApplyForce(force);
  248. _userAgent.ApplyTorque(torque);
  249. }
  250. private void EnableOrDisableFlag(DebugViewFlags flag)
  251. {
  252. if ((DebugView.Flags & flag) == flag)
  253. {
  254. DebugView.RemoveFlags(flag);
  255. }
  256. else
  257. {
  258. DebugView.AppendFlags(flag);
  259. }
  260. }
  261. public override void Draw(GameTime gameTime)
  262. {
  263. Matrix projection = Camera.SimProjection;
  264. Matrix view = Camera.SimView;
  265. DebugView.RenderDebugData(ref projection, ref view);
  266. base.Draw(gameTime);
  267. }
  268. }
  269. }