PageRenderTime 12ms CodeModel.GetById 2ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/Samples/AdvancedGameExample/Game.cs

#
C# | 197 lines | 134 code | 13 blank | 50 comment | 12 complexity | 90db46f066d1b60a7c20dc5846e503ae MD5 | raw file
  1using System.Collections.Generic;
  2using Delta.ContentSystem;
  3using Delta.ContentSystem.Rendering;
  4using Delta.Engine;
  5using Delta.Engine.Dynamic;
  6using Delta.PhysicsEngines;
  7using Delta.PhysicsEngines.VisualShapes;
  8using Delta.Rendering.Basics.Fonts;
  9using Delta.Rendering.Cameras;
 10using Delta.Rendering.Models;
 11using Delta.Utilities.Datatypes;
 12using Delta.InputSystem;
 13
 14namespace AdvancedGameExample
 15{
 16	/// <summary>
 17	/// Game class, which is the entry point for this game. Manages all the game
 18	/// logic and displays everything. More complex games obviously have more
 19	/// classes and will do things in a more organized and structured matter.
 20	/// This example game is about a 3D Pyramid of boxes, which can be pushed
 21	/// around (via Mouse, Touch or other input devices) to collapse the Pyramid
 22	/// with 3D Physics.
 23	/// </summary>
 24	class Game : DynamicModule
 25	{
 26		#region Constants
 27		/// <summary>
 28		/// Size of the pyramid. Bullet is really slow for this test so only use
 29		/// 10 * 10 pyramid. Use 20 * 20 for Jitter (handles this much quicker),
 30		/// 50 * 50 or more is also certainly possible, but slower!
 31		/// </summary>
 32		private static readonly int PyramidSize =
 33			Settings.Modules.PhysicsModule == "Bullet"
 34				? 10
 35				: 20;
 36
 37		/// <summary>
 38		/// Size of each box for the Pyramid.
 39		/// </summary>
 40		private const float BoxSize = 2.0f;
 41		#endregion
 42
 43		#region Private
 44		/// <summary>
 45		/// Mesh for drawing the ground plane
 46		/// </summary>
 47		private Mesh plane =
 48			Mesh.CreateSegmentedPlane("GroundPlane", 75, 75, 5, true, Color.White,
 49				Content.Exists("Ground", ContentType.Image)
 50					? new MaterialData()
 51					{
 52						DiffuseMapName = "Ground",
 53					}
 54					: MaterialData.Default);
 55
 56		/// <summary>
 57		/// And list of shapes to draw for the pyramid in the 3D scene.
 58		/// </summary>
 59		private readonly List<BaseVisualPhysicsShape> shapesToDraw =
 60			new List<BaseVisualPhysicsShape>();
 61		#endregion
 62
 63		#region Constructor
 64		/// <summary>
 65		/// Constructor, do additional initialization code here if needed.
 66		/// </summary>
 67		public Game()
 68			: base("Advanced Game", typeof(Application))
 69		{
 70			// Unable to continue if we have no physics (warnings are already in log)
 71			if (Physics.Instance == null)
 72			{
 73				Application.Quit();
 74				return;
 75			}
 76
 77			Physics.Instance.SetGroundPlane(true, 0.0f);
 78			// Useful for debugging:
 79			//Physics.DebugEnabled = true;
 80			// Increase gravity to be less moon-like (not perfect, just tweaking)
 81			Physics.Gravity = Physics.DefaultGravity * 10.0f;
 82			// Create a camera for the 3D world.
 83			new LookAtCamera(new Vector(10, -25, 25));
 84			// And finally setup the pyramid boxes
 85			SetupPyramid();
 86
 87			// Setup a few commands for some interaction (pushing boxes and reseting)
 88			Input.Commands[Command.UIClick].Add(delegate(CommandTrigger command)
 89			{
 90				// Create a ray from the input position (mouse, touch, whatever)
 91				Ray ray = ScreenSpace.GetRayFromScreenPoint(command.Position);
 92				// And try to grab the box we hit
 93				PhysicsBody grabBody;
 94				Vector hitNormal;
 95				float fraction;
 96				if (Physics.FindRayCast(ray, false, out grabBody, out hitNormal,
 97					out fraction) &&
 98					grabBody != null)
 99				{
100					// Activate that body and push it in the direction we are looking
101					grabBody.ApplyLinearImpulse(ray.Direction / 3.0f);
102				}
103			});
104			Input.Commands[Command.UIRightClick].Add(delegate
105			{
106				SetupPyramid();
107			});
108			Input.Commands[Command.QuitTest].Add(delegate
109			{
110				Application.Quit();
111			});
112		}
113		#endregion
114
115		#region SetupPyramid
116		/// <summary>
117		/// Setup the pyramid of physics boxes for this example game
118		/// </summary>
119		private void SetupPyramid()
120		{
121			// If we already had boxes, just restore them!
122			if (shapesToDraw.Count > 0)
123			{
124				foreach (BaseVisualPhysicsShape shape in shapesToDraw)
125				{
126					if (shape.Body != null)
127					{
128						shape.Body.AngularVelocity = Vector.Zero;
129						shape.Body.LinearVelocity = Vector.Zero;
130						shape.Body.RotationMatrix = Matrix.Identity;
131						shape.Body.Position = shape.Body.InitialPosition;
132						shape.Body.Restitution = 0.0f;
133						shape.Body.IsActive = true;
134					}
135				}
136			}
137			else
138			{
139				// Otherwise create a new pyramid
140				for (int height = 0; height < PyramidSize; height++)
141				{
142					for (int width = height; width < PyramidSize; width++)
143					{
144						// Very slightly increase height at the upper levels. This will cause
145						// the pyramid to collapse and bounce of the top parts in the
146						// beginning while the rest stays solid :)
147						VisualPhysicsBox box = new VisualPhysicsBox(
148							new Vector((width - height * 0.5f) * BoxSize * 1.1f -
149								BoxSize * 1.1f * PyramidSize / 2.0f + 1.1f, 0.0f,
150								1.0f + height * BoxSize * 1.1f),
151							BoxSize, BoxSize, BoxSize, Color.White,
152							new MaterialData()
153							{
154								DiffuseMapName =
155									Content.Exists("Box", ContentType.Image)
156										? "Box"
157										: "DeltaEngineLogo"
158							});
159
160						shapesToDraw.Add(box);
161
162						if (box.Body != null)
163						{
164							box.Body.Restitution = 0.0f;
165						}
166					}
167				}
168			}
169		}
170		#endregion
171
172		#region Run
173		/// <summary>
174		/// Run game loop, called every frame to do all game logic updating.
175		/// </summary>
176		public override void Run()
177		{
178			// Show FPS and a simple text message
179			Font.DrawTopLeftInformation(
180				"Fps: " + Time.Fps + "\n" +
181				"Click to push a box. Right click or hold touch to reset the " +
182				"Pyramid.");
183
184			// Draw the boxes of the pyramid
185			foreach (BaseVisualPhysicsShape shape in shapesToDraw)
186			{
187				shape.Draw();
188			}
189
190			// Draw the ground plane (a little below the physical ground to avoid
191			// overlapping and boxes going slightly into the ground).
192			Matrix groundTransform = Matrix.CreateTranslation(0.0f, 0.0f, -0.01f);
193			plane.Draw(ref groundTransform);
194		}
195		#endregion
196	}
197}