InputHelper.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. using System.Collections.Generic;
  2. using Microsoft.Xna.Framework;
  3. using Microsoft.Xna.Framework.Graphics;
  4. using Microsoft.Xna.Framework.Input;
  5. using Microsoft.Xna.Framework.Input.Touch;
  6. namespace FarseerPhysics.SamplesFramework
  7. {
  8. /// <summary>
  9. /// an enum of all available mouse buttons.
  10. /// </summary>
  11. public enum MouseButtons
  12. {
  13. LeftButton,
  14. MiddleButton,
  15. RightButton,
  16. ExtraButton1,
  17. ExtraButton2
  18. }
  19. public class InputHelper
  20. {
  21. private readonly List<GestureSample> _gestures = new List<GestureSample>();
  22. private GamePadState _currentGamePadState;
  23. private KeyboardState _currentKeyboardState;
  24. private MouseState _currentMouseState;
  25. private GamePadState _currentVirtualState;
  26. private GamePadState _lastGamePadState;
  27. private KeyboardState _lastKeyboardState;
  28. private MouseState _lastMouseState;
  29. private GamePadState _lastVirtualState;
  30. private bool _handleVirtualStick;
  31. private Vector2 _cursor;
  32. private bool _cursorIsValid;
  33. private bool _cursorIsVisible;
  34. private bool _cursorMoved;
  35. private Sprite _cursorSprite;
  36. #if WINDOWS_PHONE
  37. private VirtualStick _phoneStick;
  38. private VirtualButton _phoneA;
  39. private VirtualButton _phoneB;
  40. #endif
  41. private ScreenManager _manager;
  42. private Viewport _viewport;
  43. /// <summary>
  44. /// Constructs a new input state.
  45. /// </summary>
  46. public InputHelper(ScreenManager manager)
  47. {
  48. _currentKeyboardState = new KeyboardState();
  49. _currentGamePadState = new GamePadState();
  50. _currentMouseState = new MouseState();
  51. _currentVirtualState = new GamePadState();
  52. _lastKeyboardState = new KeyboardState();
  53. _lastGamePadState = new GamePadState();
  54. _lastMouseState = new MouseState();
  55. _lastVirtualState = new GamePadState();
  56. _manager = manager;
  57. _cursorIsVisible = false;
  58. _cursorMoved = false;
  59. #if WINDOWS_PHONE
  60. _cursorIsValid = false;
  61. #else
  62. _cursorIsValid = true;
  63. #endif
  64. _cursor = Vector2.Zero;
  65. _handleVirtualStick = false;
  66. }
  67. public GamePadState GamePadState
  68. {
  69. get { return _currentGamePadState; }
  70. }
  71. public KeyboardState KeyboardState
  72. {
  73. get { return _currentKeyboardState; }
  74. }
  75. public MouseState MouseState
  76. {
  77. get { return _currentMouseState; }
  78. }
  79. public GamePadState VirtualState
  80. {
  81. get { return _currentVirtualState; }
  82. }
  83. public GamePadState PreviousGamePadState
  84. {
  85. get { return _lastGamePadState; }
  86. }
  87. public KeyboardState PreviousKeyboardState
  88. {
  89. get { return _lastKeyboardState; }
  90. }
  91. public MouseState PreviousMouseState
  92. {
  93. get { return _lastMouseState; }
  94. }
  95. public GamePadState PreviousVirtualState
  96. {
  97. get { return _lastVirtualState; }
  98. }
  99. public bool ShowCursor
  100. {
  101. get { return _cursorIsVisible && _cursorIsValid; }
  102. set { _cursorIsVisible = value; }
  103. }
  104. public bool EnableVirtualStick
  105. {
  106. get { return _handleVirtualStick; }
  107. set { _handleVirtualStick = value; }
  108. }
  109. public Vector2 Cursor
  110. {
  111. get { return _cursor; }
  112. }
  113. public bool IsCursorMoved
  114. {
  115. get { return _cursorMoved; }
  116. }
  117. public bool IsCursorValid
  118. {
  119. get { return _cursorIsValid; }
  120. }
  121. public void LoadContent()
  122. {
  123. _cursorSprite = new Sprite(_manager.Content.Load<Texture2D>("Common/cursor"));
  124. #if WINDOWS_PHONE
  125. // virtual stick content
  126. _phoneStick = new VirtualStick(_manager.Content.Load<Texture2D>("Common/socket"),
  127. _manager.Content.Load<Texture2D>("Common/stick"), new Vector2(80f, 400f));
  128. Texture2D temp = _manager.Content.Load<Texture2D>("Common/buttons");
  129. _phoneA = new VirtualButton(temp, new Vector2(695f, 380f), new Rectangle(0, 0, 40, 40), new Rectangle(0, 40, 40, 40));
  130. _phoneB = new VirtualButton(temp, new Vector2(745f, 360f), new Rectangle(40, 0, 40, 40), new Rectangle(40, 40, 40, 40));
  131. #endif
  132. _viewport = _manager.GraphicsDevice.Viewport;
  133. }
  134. /// <summary>
  135. /// Reads the latest state of the keyboard and gamepad and mouse/touchpad.
  136. /// </summary>
  137. public void Update(GameTime gameTime)
  138. {
  139. _lastKeyboardState = _currentKeyboardState;
  140. _lastGamePadState = _currentGamePadState;
  141. _lastMouseState = _currentMouseState;
  142. if (_handleVirtualStick)
  143. {
  144. _lastVirtualState = _currentVirtualState;
  145. }
  146. _currentKeyboardState = Keyboard.GetState();
  147. _currentGamePadState = GamePad.GetState(PlayerIndex.One);
  148. _currentMouseState = Mouse.GetState();
  149. if (_handleVirtualStick)
  150. {
  151. #if XBOX
  152. _currentVirtualState= GamePad.GetState(PlayerIndex.One);
  153. #elif DESKTOP
  154. if (GamePad.GetState(PlayerIndex.One).IsConnected)
  155. {
  156. _currentVirtualState = GamePad.GetState(PlayerIndex.One);
  157. }
  158. else
  159. {
  160. _currentVirtualState = HandleVirtualStickWin();
  161. }
  162. #elif WINDOWS_PHONE
  163. _currentVirtualState = HandleVirtualStickWP7();
  164. #endif
  165. }
  166. _gestures.Clear();
  167. while (TouchPanel.IsGestureAvailable)
  168. {
  169. _gestures.Add(TouchPanel.ReadGesture());
  170. }
  171. // Update cursor
  172. Vector2 oldCursor = _cursor;
  173. if (_currentGamePadState.IsConnected && _currentGamePadState.ThumbSticks.Left != Vector2.Zero)
  174. {
  175. Vector2 temp = _currentGamePadState.ThumbSticks.Left;
  176. _cursor += temp * new Vector2(300f, -300f) * (float)gameTime.ElapsedGameTime.TotalSeconds;
  177. Mouse.SetPosition((int)_cursor.X, (int)_cursor.Y);
  178. }
  179. else
  180. {
  181. _cursor.X = _currentMouseState.X;
  182. _cursor.Y = _currentMouseState.Y;
  183. }
  184. _cursor.X = MathHelper.Clamp(_cursor.X, 0f, _viewport.Width);
  185. _cursor.Y = MathHelper.Clamp(_cursor.Y, 0f, _viewport.Height);
  186. if (_cursorIsValid && oldCursor != _cursor)
  187. {
  188. _cursorMoved = true;
  189. }
  190. else
  191. {
  192. _cursorMoved = false;
  193. }
  194. #if DESKTOP
  195. if (_viewport.Bounds.Contains(_currentMouseState.X, _currentMouseState.Y))
  196. {
  197. _cursorIsValid = true;
  198. }
  199. else
  200. {
  201. _cursorIsValid = false;
  202. }
  203. #elif WINDOWS_PHONE
  204. if (_currentMouseState.LeftButton == ButtonState.Pressed)
  205. {
  206. _cursorIsValid = true;
  207. }
  208. else
  209. {
  210. _cursorIsValid = false;
  211. }
  212. #endif
  213. }
  214. public void Draw()
  215. {
  216. if (_cursorIsVisible && _cursorIsValid)
  217. {
  218. _manager.SpriteBatch.Begin();
  219. _manager.SpriteBatch.Draw(_cursorSprite.Texture, _cursor, null, Color.White, 0f, _cursorSprite.Origin, 1f, SpriteEffects.None, 0f);
  220. _manager.SpriteBatch.End();
  221. }
  222. #if WINDOWS_PHONE
  223. if (_handleVirtualStick)
  224. {
  225. _manager.SpriteBatch.Begin();
  226. _phoneA.Draw(_manager.SpriteBatch);
  227. _phoneB.Draw(_manager.SpriteBatch);
  228. _phoneStick.Draw(_manager.SpriteBatch);
  229. _manager.SpriteBatch.End();
  230. }
  231. #endif
  232. }
  233. private GamePadState HandleVirtualStickWin()
  234. {
  235. Vector2 _leftStick = Vector2.Zero;
  236. List<Buttons> _buttons = new List<Buttons>();
  237. if (_currentKeyboardState.IsKeyDown(Keys.A))
  238. {
  239. _leftStick.X -= 1f;
  240. }
  241. if (_currentKeyboardState.IsKeyDown(Keys.S))
  242. {
  243. _leftStick.Y -= 1f;
  244. }
  245. if (_currentKeyboardState.IsKeyDown(Keys.D))
  246. {
  247. _leftStick.X += 1f;
  248. }
  249. if (_currentKeyboardState.IsKeyDown(Keys.W))
  250. {
  251. _leftStick.Y += 1f;
  252. }
  253. if (_currentKeyboardState.IsKeyDown(Keys.Space))
  254. {
  255. _buttons.Add(Buttons.A);
  256. }
  257. if (_currentKeyboardState.IsKeyDown(Keys.LeftControl))
  258. {
  259. _buttons.Add(Buttons.B);
  260. }
  261. if (_leftStick != Vector2.Zero)
  262. {
  263. _leftStick.Normalize();
  264. }
  265. return new GamePadState(_leftStick, Vector2.Zero, 0f, 0f, _buttons.ToArray());
  266. }
  267. private GamePadState HandleVirtualStickWP7()
  268. {
  269. List<Buttons> _buttons = new List<Buttons>();
  270. Vector2 _stick = Vector2.Zero;
  271. #if WINDOWS_PHONE
  272. _phoneA.Pressed = false;
  273. _phoneB.Pressed = false;
  274. TouchCollection touchLocations = TouchPanel.GetState();
  275. foreach (TouchLocation touchLocation in touchLocations)
  276. {
  277. _phoneA.Update(touchLocation);
  278. _phoneB.Update(touchLocation);
  279. _phoneStick.Update(touchLocation);
  280. }
  281. if (_phoneA.Pressed)
  282. {
  283. _buttons.Add(Buttons.A);
  284. }
  285. if (_phoneB.Pressed)
  286. {
  287. _buttons.Add(Buttons.B);
  288. }
  289. _stick = _phoneStick.StickPosition;
  290. #endif
  291. return new GamePadState(_stick, Vector2.Zero, 0f, 0f, _buttons.ToArray());
  292. }
  293. /// <summary>
  294. /// Helper for checking if a key was newly pressed during this update.
  295. /// </summary>
  296. public bool IsNewKeyPress(Keys key)
  297. {
  298. return (_currentKeyboardState.IsKeyDown(key) &&
  299. _lastKeyboardState.IsKeyUp(key));
  300. }
  301. public bool IsNewKeyRelease(Keys key)
  302. {
  303. return (_lastKeyboardState.IsKeyDown(key) &&
  304. _currentKeyboardState.IsKeyUp(key));
  305. }
  306. /// <summary>
  307. /// Helper for checking if a button was newly pressed during this update.
  308. /// </summary>
  309. public bool IsNewButtonPress(Buttons button)
  310. {
  311. return (_currentGamePadState.IsButtonDown(button) &&
  312. _lastGamePadState.IsButtonUp(button));
  313. }
  314. public bool IsNewButtonRelease(Buttons button)
  315. {
  316. return (_lastGamePadState.IsButtonDown(button) &&
  317. _currentGamePadState.IsButtonUp(button));
  318. }
  319. /// <summary>
  320. /// Helper for checking if a mouse button was newly pressed during this update.
  321. /// </summary>
  322. public bool IsNewMouseButtonPress(MouseButtons button)
  323. {
  324. switch (button)
  325. {
  326. case MouseButtons.LeftButton:
  327. return (_currentMouseState.LeftButton == ButtonState.Pressed &&
  328. _lastMouseState.LeftButton == ButtonState.Released);
  329. case MouseButtons.RightButton:
  330. return (_currentMouseState.RightButton == ButtonState.Pressed &&
  331. _lastMouseState.RightButton == ButtonState.Released);
  332. case MouseButtons.MiddleButton:
  333. return (_currentMouseState.MiddleButton == ButtonState.Pressed &&
  334. _lastMouseState.MiddleButton == ButtonState.Released);
  335. case MouseButtons.ExtraButton1:
  336. return (_currentMouseState.XButton1 == ButtonState.Pressed &&
  337. _lastMouseState.XButton1 == ButtonState.Released);
  338. case MouseButtons.ExtraButton2:
  339. return (_currentMouseState.XButton2 == ButtonState.Pressed &&
  340. _lastMouseState.XButton2 == ButtonState.Released);
  341. default:
  342. return false;
  343. }
  344. }
  345. /// <summary>
  346. /// Checks if the requested mouse button is released.
  347. /// </summary>
  348. /// <param name="button">The button.</param>
  349. public bool IsNewMouseButtonRelease(MouseButtons button)
  350. {
  351. switch (button)
  352. {
  353. case MouseButtons.LeftButton:
  354. return (_lastMouseState.LeftButton == ButtonState.Pressed &&
  355. _currentMouseState.LeftButton == ButtonState.Released);
  356. case MouseButtons.RightButton:
  357. return (_lastMouseState.RightButton == ButtonState.Pressed &&
  358. _currentMouseState.RightButton == ButtonState.Released);
  359. case MouseButtons.MiddleButton:
  360. return (_lastMouseState.MiddleButton == ButtonState.Pressed &&
  361. _currentMouseState.MiddleButton == ButtonState.Released);
  362. case MouseButtons.ExtraButton1:
  363. return (_lastMouseState.XButton1 == ButtonState.Pressed &&
  364. _currentMouseState.XButton1 == ButtonState.Released);
  365. case MouseButtons.ExtraButton2:
  366. return (_lastMouseState.XButton2 == ButtonState.Pressed &&
  367. _currentMouseState.XButton2 == ButtonState.Released);
  368. default:
  369. return false;
  370. }
  371. }
  372. /// <summary>
  373. /// Checks for a "menu select" input action.
  374. /// </summary>
  375. public bool IsMenuSelect()
  376. {
  377. return IsNewKeyPress(Keys.Space) ||
  378. IsNewKeyPress(Keys.Enter) ||
  379. IsNewButtonPress(Buttons.A) ||
  380. IsNewButtonPress(Buttons.Start) ||
  381. IsNewMouseButtonPress(MouseButtons.LeftButton);
  382. }
  383. public bool IsMenuPressed()
  384. {
  385. return _currentKeyboardState.IsKeyDown(Keys.Space) ||
  386. _currentKeyboardState.IsKeyDown(Keys.Enter) ||
  387. _currentGamePadState.IsButtonDown(Buttons.A) ||
  388. _currentGamePadState.IsButtonDown(Buttons.Start) ||
  389. _currentMouseState.LeftButton == ButtonState.Pressed;
  390. }
  391. public bool IsMenuReleased()
  392. {
  393. return IsNewKeyRelease(Keys.Space) ||
  394. IsNewKeyRelease(Keys.Enter) ||
  395. IsNewButtonRelease(Buttons.A) ||
  396. IsNewButtonRelease(Buttons.Start) ||
  397. IsNewMouseButtonRelease(MouseButtons.LeftButton);
  398. }
  399. /// <summary>
  400. /// Checks for a "menu cancel" input action.
  401. /// </summary>
  402. public bool IsMenuCancel()
  403. {
  404. return IsNewKeyPress(Keys.Escape) ||
  405. IsNewButtonPress(Buttons.Back);
  406. }
  407. }
  408. }