PageRenderTime 206ms CodeModel.GetById 61ms app.highlight 60ms RepoModel.GetById 80ms app.codeStats 1ms

/PhysicsEngines/Tests2D/Tutorials.cs

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