2
0

WaypointSample.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // WaypointSample.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Audio;
  13. using Microsoft.Xna.Framework.GamerServices;
  14. using Microsoft.Xna.Framework.Graphics;
  15. using Microsoft.Xna.Framework.Input;
  16. using Microsoft.Xna.Framework.Input.Touch;
  17. using Microsoft.Xna.Framework.Storage;
  18. using Microsoft.Xna.Framework.Content;
  19. using Microsoft.Xna.Framework.Media;
  20. #endregion
  21. namespace Waypoint
  22. {
  23. /// <summary>
  24. /// This sample shows how an AI can navigate from point to point using
  25. /// several different behaviors
  26. /// </summary>
  27. public class WaypointSample : Game
  28. {
  29. #region Constants
  30. /// <summary>
  31. /// Screen width in pixels
  32. /// </summary>
  33. const int screenWidth = 320;
  34. /// <summary>
  35. /// Screen height in pixels
  36. /// </summary>
  37. const int screenHeight = 480;
  38. /// <summary>
  39. /// Cursor move speed in pixels per second
  40. /// </summary>
  41. const float cursorMoveSpeed = 250.0f;
  42. #endregion
  43. #region Fields
  44. // Graphics data
  45. GraphicsDeviceManager graphics;
  46. SpriteBatch spriteBatch;
  47. // Cursor data
  48. Texture2D cursorTexture;
  49. Vector2 cursorCenter;
  50. Vector2 cursorLocation;
  51. // HUD data
  52. SpriteFont hudFont;
  53. // Where the HUD draws on the screen
  54. Vector2 hudLocation;
  55. // Input data
  56. KeyboardState previousKeyboardState;
  57. GamePadState previousGamePadState;
  58. KeyboardState currentKeyboardState;
  59. GamePadState currentGamePadState;
  60. TouchCollection currentTouchCollection;
  61. // The waypoint-following tank
  62. Tank tank;
  63. #endregion
  64. #region Initialization
  65. /// <summary>
  66. /// Construct a WaypointSample object
  67. /// </summary>
  68. public WaypointSample()
  69. {
  70. graphics = new GraphicsDeviceManager(this);
  71. Content.RootDirectory = "Content";
  72. graphics.PreferredBackBufferWidth = screenWidth;
  73. graphics.PreferredBackBufferHeight = screenHeight;
  74. tank = new Tank(this);
  75. Components.Add(tank);
  76. }
  77. /// <summary>
  78. /// Allows the game to perform any initialization it needs to before starting
  79. /// to run. This is where it can query for any required services and load and
  80. /// non-graphic related content. Calling base.Initialize will enumerate
  81. /// through any components and initialize them as well.
  82. /// </summary>
  83. protected override void Initialize()
  84. {
  85. // This places the HUD near the upper left corner of the screen
  86. hudLocation = new Vector2(
  87. (float)Math.Floor(screenWidth * .1f),
  88. (float)Math.Floor(screenHeight * .1f));
  89. // places the cursor in the center of the screen
  90. cursorLocation =
  91. new Vector2((float)screenWidth / 2, (float)screenHeight / 2);
  92. // places the tank halfway between the center of the screen and the
  93. // upper left corner
  94. tank.Reset(
  95. new Vector2((float)screenWidth / 4, (float)screenHeight / 4));
  96. base.Initialize();
  97. }
  98. /// <summary>
  99. /// LoadContent will be called once per game and is the place to load
  100. /// all of your content.
  101. /// </summary>
  102. protected override void LoadContent()
  103. {
  104. // Create a new SpriteBatch, which can be used to draw textures.
  105. spriteBatch = new SpriteBatch(GraphicsDevice);
  106. cursorTexture = Content.Load<Texture2D>("cursor");
  107. cursorCenter =
  108. new Vector2(cursorTexture.Width / 2, cursorTexture.Height / 2);
  109. hudFont = Content.Load<SpriteFont>("HUDFont");
  110. }
  111. #endregion
  112. #region Update and Draw
  113. /// <summary>
  114. /// Allows the game to run logic such as updating the world,
  115. /// checking for collisions, gathering input, and playing audio.
  116. /// </summary>
  117. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  118. protected override void Update(GameTime gameTime)
  119. {
  120. float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
  121. HandleInput(elapsedTime);
  122. base.Update(gameTime);
  123. }
  124. /// <summary>
  125. /// This is called when the game should draw itself.
  126. /// </summary>
  127. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  128. protected override void Draw(GameTime gameTime)
  129. {
  130. graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
  131. base.Draw(gameTime);
  132. string HudString = "Behavior : " + tank.BehaviorType.ToString();
  133. spriteBatch.Begin();
  134. // Draw the cursor
  135. spriteBatch.Draw(cursorTexture, cursorLocation, null, Color.White, 0f,
  136. cursorCenter, 1f, SpriteEffects.None, 0f);
  137. // Draw the string for current behavior
  138. spriteBatch.DrawString(hudFont, HudString, hudLocation, Color.White);
  139. spriteBatch.End();
  140. }
  141. #endregion
  142. #region Handle Input
  143. /// <summary>
  144. /// Read keyboard and gamepad input
  145. /// </summary>
  146. private void HandleInput(float elapsedTime)
  147. {
  148. previousGamePadState = currentGamePadState;
  149. previousKeyboardState = currentKeyboardState;
  150. currentGamePadState = GamePad.GetState(PlayerIndex.One);
  151. currentKeyboardState = Keyboard.GetState();
  152. currentTouchCollection = TouchPanel.GetState();
  153. //bool touched = false;
  154. int touchCount = 0;
  155. // tap the screen to select
  156. foreach (TouchLocation location in currentTouchCollection)
  157. {
  158. switch (location.State)
  159. {
  160. case TouchLocationState.Pressed:
  161. //touched = true;
  162. touchCount++;
  163. cursorLocation = location.Position;
  164. break;
  165. case TouchLocationState.Moved:
  166. break;
  167. case TouchLocationState.Released:
  168. break;
  169. }
  170. }
  171. // Allows the game to exit
  172. if (currentGamePadState.Buttons.Back == ButtonState.Pressed ||
  173. currentKeyboardState.IsKeyDown(Keys.Escape))
  174. this.Exit();
  175. // Update the cursor location by listening for left thumbstick input on
  176. // the GamePad and direction key input on the Keyboard, making sure to
  177. // keep the cursor inside the screen boundary
  178. cursorLocation.X +=
  179. currentGamePadState.ThumbSticks.Left.X * cursorMoveSpeed * elapsedTime;
  180. cursorLocation.Y -=
  181. currentGamePadState.ThumbSticks.Left.Y * cursorMoveSpeed * elapsedTime;
  182. if (currentKeyboardState.IsKeyDown(Keys.Up))
  183. {
  184. cursorLocation.Y -= elapsedTime * cursorMoveSpeed;
  185. }
  186. if (currentKeyboardState.IsKeyDown(Keys.Down))
  187. {
  188. cursorLocation.Y += elapsedTime * cursorMoveSpeed;
  189. }
  190. if (currentKeyboardState.IsKeyDown(Keys.Left))
  191. {
  192. cursorLocation.X -= elapsedTime * cursorMoveSpeed;
  193. }
  194. if (currentKeyboardState.IsKeyDown(Keys.Right))
  195. {
  196. cursorLocation.X += elapsedTime * cursorMoveSpeed;
  197. }
  198. cursorLocation.X = MathHelper.Clamp(cursorLocation.X, 0f, screenWidth);
  199. cursorLocation.Y = MathHelper.Clamp(cursorLocation.Y, 0f, screenHeight);
  200. // Change the tank move behavior if the user pressed B on
  201. // the GamePad or on the Keyboard.
  202. if ((previousGamePadState.Buttons.B == ButtonState.Released &&
  203. currentGamePadState.Buttons.B == ButtonState.Pressed) ||
  204. (previousKeyboardState.IsKeyUp(Keys.B) &&
  205. currentKeyboardState.IsKeyDown(Keys.B)) || ( touchCount == 2 ))
  206. {
  207. tank.CycleBehaviorType();
  208. }
  209. // Add the cursor's location to the WaypointList if the user pressed A on
  210. // the GamePad or on the Keyboard.
  211. if ((previousGamePadState.Buttons.A == ButtonState.Released &&
  212. currentGamePadState.Buttons.A == ButtonState.Pressed) ||
  213. (previousKeyboardState.IsKeyUp(Keys.A) &&
  214. currentKeyboardState.IsKeyDown(Keys.A)) || ( touchCount == 1 ))
  215. {
  216. tank.Waypoints.Enqueue(cursorLocation);
  217. }
  218. // Delete all the current waypoints and reset the tanks’ location if
  219. // the user pressed X on the GamePad or on the Keyboard.
  220. if ((previousGamePadState.Buttons.X == ButtonState.Released &&
  221. currentGamePadState.Buttons.X == ButtonState.Pressed) ||
  222. (previousKeyboardState.IsKeyUp(Keys.X) &&
  223. currentKeyboardState.IsKeyDown(Keys.X)) || ( touchCount == 3 ))
  224. {
  225. tank.Reset(
  226. new Vector2((float)screenWidth / 4, (float)screenHeight / 4));
  227. }
  228. }
  229. #endregion
  230. }
  231. }