PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Samples/AdvancedGameExample/Game.cs

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