2
0

Game1.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // Game1.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 System.Collections.Generic;
  12. using Microsoft.Xna.Framework;
  13. using Microsoft.Xna.Framework.Graphics;
  14. using Microsoft.Xna.Framework.Input;
  15. using Microsoft.Xna.Framework.Input.Touch;
  16. #endregion
  17. namespace TouchGestureSample
  18. {
  19. public class Game1 : Microsoft.Xna.Framework.Game
  20. {
  21. private GraphicsDeviceManager graphics;
  22. private SpriteBatch spriteBatch;
  23. private SpriteFont font;
  24. private Texture2D cat;
  25. // the text we display on screen, created here to make our Draw method cleaner
  26. private const string helpText =
  27. "Hold (in empty space) - Create sprite\n" +
  28. "Hold (on sprite) - Remove sprite\n" +
  29. "Tap - Change sprite color\n" +
  30. "Drag - Move sprite\n" +
  31. "Flick - Throws sprite\n" +
  32. "Pinch - Scale sprite";
  33. // a list to hold all of our sprites
  34. private List<Sprite> sprites = new List<Sprite>();
  35. // we track our selected sprite so we can drag it around
  36. private Sprite selectedSprite;
  37. public Game1()
  38. {
  39. graphics = new GraphicsDeviceManager(this);
  40. graphics.IsFullScreen = true;
  41. Content.RootDirectory = "Content";
  42. // Frame rate is 30 fps by default for Windows Phone.
  43. TargetElapsedTime = TimeSpan.FromTicks(333333);
  44. }
  45. protected override void Initialize()
  46. {
  47. // enable the gestures we care about. you must set EnabledGestures before
  48. // you can use any of the other gesture APIs.
  49. // we use both Tap and DoubleTap to workaround a bug in the XNA GS 4.0 Beta
  50. // where some Taps are missed if only Tap is specified.
  51. TouchPanel.EnabledGestures =
  52. GestureType.Hold |
  53. GestureType.Tap |
  54. GestureType.DoubleTap |
  55. GestureType.FreeDrag |
  56. GestureType.Flick |
  57. GestureType.Pinch;
  58. base.Initialize();
  59. }
  60. protected override void LoadContent()
  61. {
  62. spriteBatch = new SpriteBatch(GraphicsDevice);
  63. cat = Content.Load<Texture2D>("cat");
  64. font = Content.Load<SpriteFont>("Font");
  65. }
  66. protected override void Update(GameTime gameTime)
  67. {
  68. // Allows the game to exit
  69. if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  70. this.Exit();
  71. // handle the touch input
  72. HandleTouchInput();
  73. // update all of the sprites
  74. foreach (Sprite sprite in sprites)
  75. {
  76. sprite.Update(gameTime, GraphicsDevice.Viewport.Bounds);
  77. }
  78. base.Update(gameTime);
  79. }
  80. private void HandleTouchInput()
  81. {
  82. // we use raw touch points for selection, since they are more appropriate
  83. // for that use than gestures. so we need to get that raw touch data.
  84. TouchCollection touches = TouchPanel.GetState();
  85. // see if we have a new primary point down. when the first touch
  86. // goes down, we do hit detection to try and select one of our sprites.
  87. if (touches.Count > 0 && touches[0].State == TouchLocationState.Pressed)
  88. {
  89. // convert the touch position into a Point for hit testing
  90. Point touchPoint = new Point((int)touches[0].Position.X, (int)touches[0].Position.Y);
  91. // iterate our sprites to find which sprite is being touched. we iterate backwards
  92. // since that will cause sprites that are drawn on top to be selected before
  93. // sprites drawn on the bottom.
  94. selectedSprite = null;
  95. for (int i = sprites.Count - 1; i >= 0; i--)
  96. {
  97. Sprite sprite = sprites[i];
  98. if (sprite.HitBounds.Contains(touchPoint))
  99. {
  100. selectedSprite = sprite;
  101. break;
  102. }
  103. }
  104. if (selectedSprite != null)
  105. {
  106. // make sure we stop selected sprites
  107. selectedSprite.Velocity = Vector2.Zero;
  108. // we also move the sprite to the end of the list so it
  109. // draws on top of the other sprites
  110. sprites.Remove(selectedSprite);
  111. sprites.Add(selectedSprite);
  112. }
  113. }
  114. // next we handle all of the gestures. since we may have multiple gestures available,
  115. // we use a loop to read in all of the gestures. this is important to make sure the
  116. // TouchPanel's queue doesn't get backed up with old data
  117. while (TouchPanel.IsGestureAvailable)
  118. {
  119. // read the next gesture from the queue
  120. GestureSample gesture = TouchPanel.ReadGesture();
  121. // we can use the type of gesture to determine our behavior
  122. switch (gesture.GestureType)
  123. {
  124. // on taps, we change the color of the selected sprite
  125. case GestureType.Tap:
  126. case GestureType.DoubleTap:
  127. if (selectedSprite != null)
  128. {
  129. selectedSprite.ChangeColor();
  130. }
  131. break;
  132. // on holds, if no sprite is selected, we add a new sprite at the
  133. // hold position and make it our selected sprite. otherwise we
  134. // remove our selected sprite.
  135. case GestureType.Hold:
  136. if (selectedSprite == null)
  137. {
  138. // create the new sprite
  139. selectedSprite = new Sprite(cat);
  140. selectedSprite.Center = gesture.Position;
  141. // add it to our list
  142. sprites.Add(selectedSprite);
  143. }
  144. else
  145. {
  146. sprites.Remove(selectedSprite);
  147. selectedSprite = null;
  148. }
  149. break;
  150. // on drags, we just want to move the selected sprite with the drag
  151. case GestureType.FreeDrag:
  152. if (selectedSprite != null)
  153. {
  154. selectedSprite.Center += gesture.Delta;
  155. }
  156. break;
  157. // on flicks, we want to update the selected sprite's velocity with
  158. // the flick velocity, which is in pixels per second.
  159. case GestureType.Flick:
  160. if (selectedSprite != null)
  161. {
  162. selectedSprite.Velocity = gesture.Delta;
  163. }
  164. break;
  165. // on pinches, we want to scale the selected sprite
  166. case GestureType.Pinch:
  167. if (selectedSprite != null)
  168. {
  169. // get the current and previous locations of the two fingers
  170. Vector2 a = gesture.Position;
  171. Vector2 aOld = gesture.Position - gesture.Delta;
  172. Vector2 b = gesture.Position2;
  173. Vector2 bOld = gesture.Position2 - gesture.Delta2;
  174. // figure out the distance between the current and previous locations
  175. float d = Vector2.Distance(a, b);
  176. float dOld = Vector2.Distance(aOld, bOld);
  177. // calculate the difference between the two and use that to alter the scale
  178. float scaleChange = (d - dOld) * .01f;
  179. selectedSprite.Scale += scaleChange;
  180. }
  181. break;
  182. }
  183. }
  184. // lastly, if there are no raw touch points, we make sure no sprites are selected.
  185. // this happens after we handle gestures because some gestures like taps and flicks
  186. // will come in on the same frame as our raw touch points report no touches and we
  187. // still want to use the selected sprite for those gestures.
  188. if (touches.Count == 0)
  189. {
  190. selectedSprite = null;
  191. }
  192. }
  193. protected override void Draw(GameTime gameTime)
  194. {
  195. GraphicsDevice.Clear(Color.CornflowerBlue);
  196. spriteBatch.Begin();
  197. // draw all sprites first
  198. foreach (Sprite sprite in sprites)
  199. {
  200. sprite.Draw(spriteBatch);
  201. }
  202. // draw our helper text so users know what they're doing.
  203. spriteBatch.DrawString(font, helpText, new Vector2(10f, 32f), Color.White);
  204. spriteBatch.End();
  205. base.Draw(gameTime);
  206. }
  207. }
  208. }