PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/PhysicsEngines/Tests2D/Tutorials.cs

#
C# | 400 lines | 242 code | 45 blank | 113 comment | 8 complexity | 17e8700a78133f33ce4700f711ddc3c7 MD5 | raw file
Possible License(s): Apache-2.0
  1. using System.Collections.Generic;
  2. using Delta.Engine;
  3. using Delta.InputSystem;
  4. using Delta.Rendering.Basics.Drawing;
  5. using Delta.Rendering.Basics.Fonts;
  6. using Delta.Utilities;
  7. using Delta.Utilities.Datatypes;
  8. using NUnit.Framework;
  9. namespace Delta.PhysicsEngines.Tests2D
  10. {
  11. /// <summary>
  12. /// Tutorials for Physics 2D
  13. /// </summary>
  14. public class Tutorials
  15. {
  16. #region Simple2DSimulation (Static)
  17. /// <summary>
  18. /// Tutorial: 2D Physics Tutorial 1: Simple 2D Simulation
  19. /// Difficulty: Easy
  20. /// Description: Simple physics simulation with a ground, box and circle.
  21. /// Image: http://DeltaEngine.net/Icons/Physics2DTutorial1.png
  22. /// </summary>
  23. [Test, Category("Visual")]
  24. public static void Simple2DSimulation()
  25. {
  26. Physics.Gravity = new Vector(0f, 0.0981f, 0f);
  27. // Enable debug drawing
  28. Physics.DebugEnabled = true;
  29. float radius = 0.05f;
  30. float mass = 1.0f;
  31. PhysicsBody ball = Physics.CreateCircle(radius, mass);
  32. ball.Position = new Vector(0.45f, 0.1f, 0f);
  33. ball.Friction = 1.0f;
  34. ball.DebugColor = Color.Red;
  35. Rectangle boxRect = new Rectangle(0f, 0f, 0.05f, 0.05f);
  36. PhysicsBody box = Physics.CreateRectangle(boxRect.Width,
  37. boxRect.Height, 1.0f);
  38. box.Position = new Vector(0.5f, 0.4f, 0.0f);
  39. box.Friction = 1.0f;
  40. box.DebugColor = Color.Green;
  41. // set our ground
  42. Rectangle groundRect = new Rectangle(0.1f, 0.65f, 0.8f, 0.1f);
  43. PhysicsBody ground = Physics.CreateRectangle(groundRect.Width,
  44. groundRect.Height, 1f);
  45. ground.Position = new Vector(groundRect.Center, 0.0f);
  46. ground.IsStatic = true;
  47. ground.Friction = 1.0f;
  48. ground.DebugColor = Color.Yellow;
  49. // And start the application.
  50. Application.Start();
  51. }
  52. #endregion
  53. #region JointsSimulation (Static)
  54. /// <summary>
  55. /// Tutorial: 2D Physics Tutorial 2: Joints Simulation
  56. /// Difficulty: Easy
  57. /// Description: Simple 2d physics simulation with joints.
  58. /// Image: http://DeltaEngine.net/Icons/Physics2DTutorial2.png
  59. /// </summary>
  60. [Test, Category("Visual")]
  61. public static void JointsSimulation()
  62. {
  63. Physics.Gravity = new Vector(0f, 0.0981f, 0f);
  64. // Enable debug drawing
  65. Physics.DebugEnabled = true;
  66. PhysicsBody box = Physics.CreateRectangle(0.05f, 0.05f, 1f);
  67. box.Position = new Vector(0.3f, 0.35f, 0f);
  68. box.Friction = 1f;
  69. box.DebugColor = Color.Green;
  70. PhysicsBody box2 = Physics.CreateRectangle(0.05f, 0.05f, 1f);
  71. box2.Position = new Vector(0.4f, 0.3f, 0f);
  72. box2.Friction = 1f;
  73. box2.DebugColor = Color.Yellow;
  74. // Create angle joint
  75. PhysicsJoint joint = Physics.CreatePointPointDistance(
  76. box, box2,
  77. new Vector(6.0f, 0.0f, 0.0f),
  78. new Vector(0.0f, -1.0f, 0.0f));
  79. // set our ground
  80. Rectangle groundRect = new Rectangle(0.2f, 0.65f, 0.7f, 0.1f);
  81. PhysicsBody ground = Physics.CreateRectangle(groundRect.Width,
  82. groundRect.Height, 1f);
  83. ground.Position = new Vector(groundRect.Center, 0f);
  84. ground.IsStatic = true;
  85. ground.Friction = 1f;
  86. ground.DebugColor = Color.Yellow;
  87. Application.Start(delegate
  88. {
  89. Font.Default.Draw("You can control a box with W/A/S/D",
  90. ScreenSpace.DrawArea);
  91. // Up movement
  92. if (Input.Keyboard.IsPressed(InputButton.W))
  93. {
  94. box.ApplyLinearImpulse(new Vector(0, -2, 0));
  95. }
  96. // Down movement
  97. if (Input.Keyboard.IsPressed(InputButton.S))
  98. {
  99. box.ApplyLinearImpulse(new Vector(0, 2, 0));
  100. }
  101. // Left movement
  102. if (Input.Keyboard.IsPressed(InputButton.A))
  103. {
  104. box.ApplyLinearImpulse(new Vector(-2, 0, 0));
  105. }
  106. // Right movement
  107. if (Input.Keyboard.IsPressed(InputButton.D))
  108. {
  109. box.ApplyLinearImpulse(new Vector(2, 0, 0));
  110. }
  111. });
  112. }
  113. #endregion
  114. #region BouncyBallSimulation (Static)
  115. /// <summary>
  116. /// Tutorial: 2D Physics Tutorial 3: Bouncy Ball Simulation
  117. /// Difficulty: Easy
  118. /// Description: Simple 2d physics simulation of a bouncy ball.
  119. /// Image: http://DeltaEngine.net/Icons/Physics2DTutorial3.png
  120. /// </summary>
  121. [Test, Category("Visual")]
  122. public static void BouncyBallSimulation()
  123. {
  124. Physics.Gravity = new Vector(0f, 0.0981f, 0f);
  125. // Enable debug drawing
  126. Physics.DebugEnabled = true;
  127. // Border rectangle
  128. Rectangle leftRect = new Rectangle(0.0f, 0.0f, 0.1f, 1.0f);
  129. Rectangle topRect = new Rectangle(0.1f, 0.1f, 0.8f, 0.1f);
  130. Rectangle rightRect = new Rectangle(0.9f, 0.0f, 0.1f, 1.0f);
  131. Rectangle bottomRect = new Rectangle(0.05f, 0.8f, 0.85f, 0.2f);
  132. PhysicsBody leftBorder = Physics.CreateRectangle(leftRect.Width,
  133. leftRect.Height, 5f);
  134. leftBorder.Friction = 1f;
  135. leftBorder.Restitution = 1f;
  136. leftBorder.Position2D = leftRect.Center;
  137. leftBorder.IsStatic = true;
  138. leftBorder.DebugColor = Color.White;
  139. PhysicsBody topBorder = Physics.CreateRectangle(topRect.Width,
  140. topRect.Height, 5f);
  141. topBorder.Friction = 1f;
  142. topBorder.Restitution = 1f;
  143. topBorder.Position2D = topRect.Center;
  144. topBorder.IsStatic = true;
  145. topBorder.DebugColor = Color.White;
  146. PhysicsBody rightBorder = Physics.CreateRectangle(rightRect.Width,
  147. rightRect.Height, 5f);
  148. rightBorder.Friction = 1f;
  149. rightBorder.Restitution = 1f;
  150. rightBorder.Position2D = rightRect.Center;
  151. rightBorder.IsStatic = true;
  152. rightBorder.DebugColor = Color.White;
  153. PhysicsBody bottomBorder = Physics.CreateRectangle(bottomRect.Width,
  154. bottomRect.Height, 5f);
  155. bottomBorder.Friction = 1f;
  156. bottomBorder.Restitution = 1f;
  157. bottomBorder.Position2D = bottomRect.Center;
  158. bottomBorder.IsStatic = true;
  159. bottomBorder.Rotation = 10f;
  160. // Create a ball;
  161. PhysicsBody ball = Physics.CreateCircle(0.035f, 1f);
  162. ball.Friction = 0.3f;
  163. ball.Restitution = 1f;
  164. ball.Position2D = new Point(0.2f, 0.5f);
  165. ball.DebugColor = Color.CornflowerBlue;
  166. Application.Start();
  167. }
  168. #endregion
  169. #region RayCasting2D (Static)
  170. /// <summary>
  171. /// Tutorial: 2D Physics Tutorial 4: Ray Casting in 2D
  172. /// Difficulty: Easy
  173. /// Description: Simple 2d ray cast with a box.
  174. /// Image: http://DeltaEngine.net/Icons/Physics2DTutorial4.png
  175. /// </summary>
  176. [Test, Category("Visual")]
  177. public static void RayCasting2D()
  178. {
  179. Physics.Gravity = new Vector(0f, 0.0981f, 0f);
  180. // Enable debug drawing
  181. Physics.DebugEnabled = true;
  182. // set our ground
  183. Rectangle groundRect = new Rectangle(0.6f, 0.4f, 0.2f, 0.2f);
  184. PhysicsBody ground = Physics.CreateRectangle(groundRect.Width,
  185. groundRect.Height, 1f);
  186. ground.Position = new Vector(groundRect.Center, 0.0f);
  187. ground.IsStatic = true;
  188. ground.Friction = 1.0f;
  189. ground.DebugColor = Color.Yellow;
  190. Point rayStart = new Point(0f, 0.5f);
  191. Point rayEnd = ScreenSpace.DrawArea.TopRight;
  192. Application.Start(delegate
  193. {
  194. // Draw the ray.
  195. Line.Draw(rayStart, rayEnd, Color.Green);
  196. // And perform the ray cast.
  197. PhysicsBody foundObject;
  198. Point normal;
  199. float fraction;
  200. if (Physics.FindRayCast2D(rayStart, rayEnd, out foundObject,
  201. out normal, out fraction))
  202. {
  203. ground.Rotation += 10f * Time.Delta;
  204. }
  205. // Update the ray movement.
  206. rayEnd.Y += 0.1f * Time.Delta;
  207. if (rayEnd.Y >= ScreenSpace.DrawArea.Bottom)
  208. {
  209. rayEnd.Y = ScreenSpace.DrawArea.Top;
  210. }
  211. });
  212. }
  213. #endregion
  214. #region CollisionEvents (Static)
  215. /// <summary>
  216. /// Tutorial: 2D Physics Tutorial 5: Collision Events
  217. /// Difficulty: Easy
  218. /// Description: Simple tutorial showing how to use physic collision events.
  219. /// Image: http://DeltaEngine.net/Icons/Physics2DTutorial5.png
  220. /// </summary>
  221. [Test, Category("Visual")]
  222. public static void CollisionEvents()
  223. {
  224. Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
  225. // Enable debug drawing
  226. Physics.DebugEnabled = true;
  227. PhysicsBody ball = Physics.CreateCircle(0.05f, 1f);
  228. ball.Position = new Vector(0.2f, 0.3f, 0f);
  229. ball.Friction = 0.3f;
  230. ball.Restitution = 1f;
  231. ball.DebugColor = Color.Red;
  232. ball.Name = "Ball";
  233. PhysicsBody box = Physics.CreateRectangle(0.05f, 0.05f, 1f);
  234. box.Position = new Vector(0.5f, 0.4f, 0f);
  235. box.Friction = 1f;
  236. box.DebugColor = Color.Green;
  237. box.Name = "Box";
  238. Rectangle groundRect = new Rectangle(0.1f, 0.65f, 0.8f, 0.1f);
  239. // set our ground
  240. PhysicsBody ground = Physics.CreateRectangle(groundRect.Width,
  241. groundRect.Height, 1f);
  242. ground.Position = new Vector(groundRect.Center, 0f);
  243. ground.IsStatic = true;
  244. ground.Friction = 1f;
  245. ground.DebugColor = Color.Yellow;
  246. ground.Name = "Plane";
  247. ground.CollisionBegin += delegate(PhysicsBody other)
  248. {
  249. Log.Info("Body '" + other.Name + "' collides with the plane.", false);
  250. };
  251. ground.CollisionEnd += delegate(PhysicsBody other)
  252. {
  253. Log.Info("Body '" + other.Name + "' ends collision with the plane.",
  254. false);
  255. };
  256. Application.Start();
  257. }
  258. #endregion
  259. #region PyramidSimulation (Static)
  260. /// <summary>
  261. /// Tutorial: 2D Physics Tutorial 6: Pyramid Simulation
  262. /// Difficulty: Normal
  263. /// Description: Simple 2d physics simulation with pyramid
  264. /// Image: http://DeltaEngine.net/Icons/Physics2DTutorial6.png
  265. /// </summary>
  266. [Test, Category("Visual")]
  267. public static void PyramidSimulation()
  268. {
  269. Physics.Gravity = new Vector(0f, 0.0981f, 0f);
  270. // Enable debug drawing
  271. Physics.DebugEnabled = true;
  272. Rectangle groundRect = new Rectangle(0.2f, 0.65f, 0.7f, 0.1f);
  273. const int PyramidBaseBodyCount = 10;
  274. List<PhysicsBody> bodies = new List<PhysicsBody>();
  275. Point rowStart = new Point(0.75f, 0.7f);
  276. rowStart.Y -= 0.05f + PyramidBaseBodyCount * 0.11f;
  277. Point deltaRow = new Point(-0.0625f, 0.11f);
  278. const float spacing = 0.075f;
  279. for (int i = 0; i < PyramidBaseBodyCount; ++i)
  280. {
  281. Point pos = rowStart;
  282. for (int j = 0; j < i + 1; ++j)
  283. {
  284. PhysicsBody rect = Physics.CreateRectangle(0.05f, 0.05f, 1.0f);
  285. rect.Position2D = pos;
  286. //rect.Friction = 1.0f;
  287. rect.DebugColor = Color.Red;
  288. bodies.Add(rect);
  289. pos.X += spacing;
  290. }
  291. rowStart += deltaRow;
  292. }
  293. // set our ground
  294. PhysicsBody ground = Physics.CreateRectangle(groundRect.Width,
  295. groundRect.Height, 1f);
  296. ground.Position = new Vector(groundRect.Center, 0f);
  297. ground.IsStatic = true;
  298. ground.Friction = 1f;
  299. ground.DebugColor = Color.Yellow;
  300. Application.Start();
  301. }
  302. #endregion
  303. /*TODO: integrate: tst physics projectile firing (farseer high fps bug)
  304. class Game : DynamicModule
  305. {
  306. PhysicsBody projectile = null;
  307. private PhysicsBody ground = null;
  308. public Game()
  309. : base("Simple Game", typeof(Application))
  310. {
  311. Settings.Extra.LimitFramerateNumber = 60;
  312. Settings.Modules.PhysicsModule = "Farseer";
  313. Physics.Gravity = new Vector(0f, 1f, 0f);
  314. Physics.DebugEnabled = true;
  315. Rectangle groundRect = new Rectangle(0f, 0.74f, 1f, 0.01f);
  316. ground = Physics.CreateRectangle(groundRect.Width, groundRect.Height, 1f);
  317. ground.Position = new Vector(groundRect.Center, 0.0f);
  318. ground.IsStatic = true;
  319. ground.Friction = 1.0f;
  320. ground.DebugColor = Color.Yellow;
  321. Input.Commands[Command.UIClick].Add(delegate(CommandTrigger input)
  322. {
  323. // Kill the old projectile
  324. if (projectile != null)
  325. {
  326. projectile.Remove();
  327. }
  328. projectile = Physics.CreateRectangle(0.06f, 0.01f, 1f);
  329. projectile.Position2D = new Point(0.205f, 0.66f);
  330. projectile.Mass = 1.0f;
  331. projectile.Friction = 1f;
  332. projectile.DebugColor = Color.Red;
  333. projectile.ApplyLinearImpulse(new Vector(new Point(665f, -746f), 0f));
  334. Log.Info("Peng " + Time.Milliseconds);
  335. Log.Info("LinearVelocity=" + projectile.LinearVelocity, false);
  336. Log.Info("AngularVelocity=" + projectile.AngularVelocity, false);
  337. Log.Info("Restitution=" + projectile.Restitution, false);
  338. });
  339. }
  340. public override void Run()
  341. {
  342. if (projectile != null)
  343. {
  344. Log.Info("GetDebugInfo=" + projectile.GetDebugInfo(), false);
  345. }
  346. }
  347. }
  348. */
  349. }
  350. }