WaypointSample.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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 = 640;
  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. MouseState previousMouseState;
  59. KeyboardState currentKeyboardState;
  60. GamePadState currentGamePadState;
  61. MouseState currentMouseState;
  62. TouchCollection currentTouchCollection;
  63. // The waypoint-following tank
  64. Tank tank;
  65. #endregion
  66. #region Initialization
  67. /// <summary>
  68. /// Construct a WaypointSample object
  69. /// </summary>
  70. public WaypointSample()
  71. {
  72. graphics = new GraphicsDeviceManager(this);
  73. Content.RootDirectory = "Content";
  74. graphics.PreferredBackBufferWidth = screenWidth;
  75. graphics.PreferredBackBufferHeight = screenHeight;
  76. tank = new Tank(this);
  77. Components.Add(tank);
  78. }
  79. /// <summary>
  80. /// Allows the game to perform any initialization it needs to before starting
  81. /// to run. This is where it can query for any required services and load and
  82. /// non-graphic related content. Calling base.Initialize will enumerate
  83. /// through any components and initialize them as well.
  84. /// </summary>
  85. protected override void Initialize()
  86. {
  87. // This places the HUD near the upper left corner of the screen
  88. hudLocation = new Vector2(
  89. (float)Math.Floor(screenWidth * .1f),
  90. (float)Math.Floor(screenHeight * .1f));
  91. // places the cursor in the center of the screen
  92. cursorLocation =
  93. new Vector2((float)screenWidth / 2, (float)screenHeight / 2);
  94. // places the tank halfway between the center of the screen and the
  95. // upper left corner
  96. tank.Reset(
  97. new Vector2((float)screenWidth / 4, (float)screenHeight / 4));
  98. base.Initialize();
  99. }
  100. /// <summary>
  101. /// LoadContent will be called once per game and is the place to load
  102. /// all of your content.
  103. /// </summary>
  104. protected override void LoadContent()
  105. {
  106. // Create a new SpriteBatch, which can be used to draw textures.
  107. spriteBatch = new SpriteBatch(GraphicsDevice);
  108. cursorTexture = Content.Load<Texture2D>("cursor");
  109. cursorCenter =
  110. new Vector2(cursorTexture.Width / 2, cursorTexture.Height / 2);
  111. hudFont = Content.Load<SpriteFont>("HUDFont");
  112. }
  113. #endregion
  114. #region Update and Draw
  115. /// <summary>
  116. /// Allows the game to run logic such as updating the world,
  117. /// checking for collisions, gathering input, and playing audio.
  118. /// </summary>
  119. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  120. protected override void Update(GameTime gameTime)
  121. {
  122. float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
  123. HandleInput(elapsedTime);
  124. base.Update(gameTime);
  125. }
  126. /// <summary>
  127. /// This is called when the game should draw itself.
  128. /// </summary>
  129. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  130. protected override void Draw(GameTime gameTime)
  131. {
  132. graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
  133. base.Draw(gameTime);
  134. string HudString = "Behavior : " + tank.BehaviorType.ToString();
  135. spriteBatch.Begin();
  136. // Draw the cursor
  137. spriteBatch.Draw(cursorTexture, cursorLocation, null, Color.White, 0f,
  138. cursorCenter, 1f, SpriteEffects.None, 0f);
  139. // Draw the string for current behavior
  140. spriteBatch.DrawString(hudFont, HudString, hudLocation, Color.White);
  141. spriteBatch.End();
  142. }
  143. #endregion
  144. #region Handle Input
  145. /// <summary>
  146. /// Read keyboard and gamepad input
  147. /// </summary>
  148. private void HandleInput(float elapsedTime)
  149. {
  150. previousGamePadState = currentGamePadState;
  151. previousKeyboardState = currentKeyboardState;
  152. previousMouseState = currentMouseState;
  153. currentGamePadState = GamePad.GetState(PlayerIndex.One);
  154. currentKeyboardState = Keyboard.GetState();
  155. currentMouseState = Mouse.GetState();
  156. currentTouchCollection = TouchPanel.GetState();
  157. //bool touched = false;
  158. int touchCount = 0;
  159. // tap the screen to select
  160. foreach (TouchLocation location in currentTouchCollection)
  161. {
  162. switch (location.State)
  163. {
  164. case TouchLocationState.Pressed:
  165. //touched = true;
  166. touchCount++;
  167. cursorLocation = location.Position;
  168. break;
  169. case TouchLocationState.Moved:
  170. break;
  171. case TouchLocationState.Released:
  172. break;
  173. }
  174. }
  175. if ( currentMouseState.LeftButton == ButtonState.Released && previousMouseState.LeftButton == ButtonState.Pressed)
  176. {
  177. cursorLocation.X = currentMouseState.X;
  178. cursorLocation.Y = currentMouseState.Y;
  179. touchCount = 1;
  180. }
  181. if (currentMouseState.MiddleButton == ButtonState.Released && previousMouseState.MiddleButton == ButtonState.Pressed) {
  182. touchCount = 2;
  183. }
  184. if (currentMouseState.RightButton == ButtonState.Released && previousMouseState.RightButton == ButtonState.Pressed) {
  185. touchCount = 3;
  186. }
  187. // Allows the game to exit
  188. if (currentGamePadState.Buttons.Back == ButtonState.Pressed ||
  189. currentKeyboardState.IsKeyDown(Keys.Escape))
  190. this.Exit();
  191. // Update the cursor location by listening for left thumbstick input on
  192. // the GamePad and direction key input on the Keyboard, making sure to
  193. // keep the cursor inside the screen boundary
  194. cursorLocation.X +=
  195. currentGamePadState.ThumbSticks.Left.X * cursorMoveSpeed * elapsedTime;
  196. cursorLocation.Y -=
  197. currentGamePadState.ThumbSticks.Left.Y * cursorMoveSpeed * elapsedTime;
  198. if (currentKeyboardState.IsKeyDown(Keys.Up))
  199. {
  200. cursorLocation.Y -= elapsedTime * cursorMoveSpeed;
  201. }
  202. if (currentKeyboardState.IsKeyDown(Keys.Down))
  203. {
  204. cursorLocation.Y += elapsedTime * cursorMoveSpeed;
  205. }
  206. if (currentKeyboardState.IsKeyDown(Keys.Left))
  207. {
  208. cursorLocation.X -= elapsedTime * cursorMoveSpeed;
  209. }
  210. if (currentKeyboardState.IsKeyDown(Keys.Right))
  211. {
  212. cursorLocation.X += elapsedTime * cursorMoveSpeed;
  213. }
  214. cursorLocation.X = MathHelper.Clamp(cursorLocation.X, 0f, screenWidth);
  215. cursorLocation.Y = MathHelper.Clamp(cursorLocation.Y, 0f, screenHeight);
  216. // Change the tank move behavior if the user pressed B on
  217. // the GamePad or on the Keyboard.
  218. if ((previousGamePadState.Buttons.B == ButtonState.Released &&
  219. currentGamePadState.Buttons.B == ButtonState.Pressed) ||
  220. (previousKeyboardState.IsKeyUp(Keys.B) &&
  221. currentKeyboardState.IsKeyDown(Keys.B)) || ( touchCount == 2 ))
  222. {
  223. tank.CycleBehaviorType();
  224. }
  225. // Add the cursor's location to the WaypointList if the user pressed A on
  226. // the GamePad or on the Keyboard.
  227. if ((previousGamePadState.Buttons.A == ButtonState.Released &&
  228. currentGamePadState.Buttons.A == ButtonState.Pressed) ||
  229. (previousKeyboardState.IsKeyUp(Keys.A) &&
  230. currentKeyboardState.IsKeyDown(Keys.A)) || ( touchCount == 1 ))
  231. {
  232. tank.Waypoints.Enqueue(cursorLocation);
  233. }
  234. // Delete all the current waypoints and reset the tanks’ location if
  235. // the user pressed X on the GamePad or on the Keyboard.
  236. if ((previousGamePadState.Buttons.X == ButtonState.Released &&
  237. currentGamePadState.Buttons.X == ButtonState.Pressed) ||
  238. (previousKeyboardState.IsKeyUp(Keys.X) &&
  239. currentKeyboardState.IsKeyDown(Keys.X)) || ( touchCount == 3 ))
  240. {
  241. tank.Reset(
  242. new Vector2((float)screenWidth / 4, (float)screenHeight / 4));
  243. }
  244. }
  245. #endregion
  246. }
  247. }