GameplayScreen.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // GameplayScreen.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 System.Linq;
  13. using System.Text;
  14. using Microsoft.Xna.Framework;
  15. using Microsoft.Xna.Framework.Graphics;
  16. using Microsoft.Xna.Framework.Audio;
  17. using System.IO.IsolatedStorage;
  18. using System.IO;
  19. using Microsoft.Xna.Framework.Input;
  20. using Microsoft.Xna.Framework.Input.Touch;
  21. //using Microsoft.Devices.Sensors;
  22. using GameStateManagement;
  23. #endregion
  24. namespace CatapultGame
  25. {
  26. class GameplayScreen : GameScreen
  27. {
  28. #region Fields
  29. // Texture Members
  30. Texture2D foregroundTexture;
  31. Texture2D cloud1Texture;
  32. Texture2D cloud2Texture;
  33. Texture2D mountainTexture;
  34. Texture2D skyTexture;
  35. Texture2D hudBackgroundTexture;
  36. Texture2D ammoTypeTexture;
  37. Texture2D windArrowTexture;
  38. Texture2D defeatTexture;
  39. Texture2D victoryTexture;
  40. SpriteFont hudFont;
  41. // Rendering members
  42. Vector2 cloud1Position;
  43. Vector2 cloud2Position;
  44. Vector2 playerHUDPosition;
  45. Vector2 computerHUDPosition;
  46. Vector2 windArrowPosition;
  47. // Gameplay members
  48. Human player;
  49. AI computer;
  50. Vector2 wind;
  51. bool changeTurn;
  52. bool isHumanTurn;
  53. bool gameOver;
  54. Random random;
  55. const int minWind = 0;
  56. const int maxWind = 10;
  57. // Helper members
  58. bool isDragging;
  59. #endregion
  60. #region Initialization
  61. public GameplayScreen()
  62. {
  63. EnabledGestures = GestureType.FreeDrag |
  64. GestureType.DragComplete |
  65. GestureType.Tap;
  66. random = new Random();
  67. }
  68. #endregion
  69. #region Content Loading/Unloading
  70. /// <summary>
  71. /// Loads the game assets and initializes "players"
  72. /// </summary>
  73. public override void LoadContent()
  74. {
  75. base.LoadContent();
  76. // Start the game
  77. Start();
  78. }
  79. public void LoadAssets()
  80. {
  81. // Load textures
  82. foregroundTexture = Load<Texture2D>("Textures/Backgrounds/gameplay_screen");
  83. cloud1Texture = Load<Texture2D>("Textures/Backgrounds/cloud1");
  84. cloud2Texture = Load<Texture2D>("Textures/Backgrounds/cloud2");
  85. mountainTexture = Load<Texture2D>("Textures/Backgrounds/mountain");
  86. skyTexture = Load<Texture2D>("Textures/Backgrounds/sky");
  87. defeatTexture = Load<Texture2D>("Textures/Backgrounds/defeat");
  88. victoryTexture = Load<Texture2D>("Textures/Backgrounds/victory");
  89. hudBackgroundTexture = Load<Texture2D>("Textures/HUD/hudBackground");
  90. windArrowTexture = Load<Texture2D>("Textures/HUD/windArrow");
  91. ammoTypeTexture = Load<Texture2D>("Textures/HUD/ammoType");
  92. // Load font
  93. hudFont = Load<SpriteFont>("Fonts/HUDFont");
  94. // Define initial cloud position
  95. cloud1Position = new Vector2(224 - cloud1Texture.Width, 32);
  96. cloud2Position = new Vector2(64, 90);
  97. // Define initial HUD positions
  98. playerHUDPosition = new Vector2(7, 7);
  99. computerHUDPosition = new Vector2(613, 7);
  100. windArrowPosition = new Vector2(345, 46);
  101. // Initialize human & AI players
  102. player = new Human(ScreenManager.Game, ScreenManager.SpriteBatch);
  103. player.Initialize();
  104. player.Name = "Player";
  105. computer = new AI(ScreenManager.Game, ScreenManager.SpriteBatch);
  106. computer.Initialize();
  107. computer.Name = "Phone";
  108. // Identify enemies
  109. player.Enemy = computer;
  110. computer.Enemy = player;
  111. }
  112. #endregion
  113. #region Update
  114. /// <summary>
  115. /// Runs one frame of update for the game.
  116. /// </summary>
  117. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  118. public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
  119. {
  120. float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
  121. // Check it one of the players reached 5 and stop the game
  122. if ((player.Catapult.GameOver || computer.Catapult.GameOver) &&
  123. (gameOver == false))
  124. {
  125. gameOver = true;
  126. if (player.Score > computer.Score)
  127. {
  128. AudioManager.PlaySound("gameOver_Win");
  129. }
  130. else
  131. {
  132. AudioManager.PlaySound("gameOver_Lose");
  133. }
  134. return;
  135. }
  136. // If Reset flag raised and both catapults are not animating -
  137. // active catapult finished the cycle, new turn!
  138. if ((player.Catapult.CurrentState == CatapultState.Reset ||
  139. computer.Catapult.CurrentState == CatapultState.Reset) &&
  140. !(player.Catapult.AnimationRunning ||
  141. computer.Catapult.AnimationRunning))
  142. {
  143. changeTurn = true;
  144. if (player.IsActive == true) //Last turn was a human turn?
  145. {
  146. player.IsActive = false;
  147. computer.IsActive = true;
  148. isHumanTurn = false;
  149. player.Catapult.CurrentState = CatapultState.Idle;
  150. computer.Catapult.CurrentState = CatapultState.Aiming;
  151. }
  152. else //It was an AI turn
  153. {
  154. player.IsActive = true;
  155. computer.IsActive = false;
  156. isHumanTurn = true;
  157. computer.Catapult.CurrentState = CatapultState.Idle;
  158. player.Catapult.CurrentState = CatapultState.Idle;
  159. }
  160. }
  161. if (changeTurn)
  162. {
  163. // Update wind
  164. wind = new Vector2(random.Next(-1, 2),
  165. random.Next(minWind, maxWind + 1));
  166. // Set new wind value to the players and
  167. player.Catapult.Wind = computer.Catapult.Wind =
  168. wind.X > 0 ? wind.Y : -wind.Y;
  169. changeTurn = false;
  170. }
  171. // Update the players
  172. player.Update(gameTime);
  173. computer.Update(gameTime);
  174. // Updates the clouds position
  175. UpdateClouds(elapsed);
  176. base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
  177. }
  178. #endregion
  179. #region Draw
  180. /// <summary>
  181. /// Draw the game world, effects, and HUD
  182. /// </summary>
  183. /// <param name="gameTime">The elapsed time since last Draw</param>
  184. public override void Draw(GameTime gameTime)
  185. {
  186. ScreenManager.SpriteBatch.Begin();
  187. // Render all parts of the screen
  188. DrawBackground();
  189. DrawComputer(gameTime);
  190. DrawPlayer(gameTime);
  191. DrawHud();
  192. ScreenManager.SpriteBatch.End();
  193. }
  194. #endregion
  195. #region Input
  196. /// <summary>
  197. /// Input helper method provided by GameScreen. Packages up the various input
  198. /// values for ease of use.
  199. /// </summary>
  200. /// <param name="input">The state of the gamepads</param>
  201. public override void HandleInput(InputState input)
  202. {
  203. if (input == null)
  204. throw new ArgumentNullException("input");
  205. if (gameOver)
  206. {
  207. if (input.IsPauseGame(null))
  208. {
  209. FinishCurrentGame();
  210. }
  211. foreach (GestureSample gestureSample in input.Gestures)
  212. {
  213. if (gestureSample.GestureType == GestureType.Tap)
  214. {
  215. FinishCurrentGame();
  216. }
  217. }
  218. return;
  219. }
  220. if (input.IsPauseGame(null))
  221. {
  222. PauseCurrentGame();
  223. }
  224. else if (isHumanTurn &&
  225. (player.Catapult.CurrentState == CatapultState.Idle ||
  226. player.Catapult.CurrentState == CatapultState.Aiming))
  227. {
  228. // First we try with mouse input
  229. player.HandleInput(input);
  230. if (input.MouseGesture == MouseGestureType.FreeDrag)
  231. isDragging = true;
  232. else if (input.MouseGesture == MouseGestureType.DragComplete)
  233. isDragging = false;
  234. // Read all available gestures
  235. foreach (GestureSample gestureSample in input.Gestures)
  236. {
  237. if (gestureSample.GestureType == GestureType.FreeDrag)
  238. isDragging = true;
  239. else if (gestureSample.GestureType == GestureType.DragComplete)
  240. isDragging = false;
  241. player.HandleInput(gestureSample);
  242. }
  243. }
  244. }
  245. #endregion
  246. #region Update Helpers
  247. private void UpdateClouds(float elapsedTime)
  248. {
  249. // Move the clouds according to the wind
  250. int windDirection = wind.X > 0 ? 1 : -1;
  251. cloud1Position += new Vector2(24.0f, 0.0f) * elapsedTime *
  252. windDirection * wind.Y;
  253. if (cloud1Position.X > ScreenManager.GraphicsDevice.Viewport.Width)
  254. cloud1Position.X = -cloud1Texture.Width * 2.0f;
  255. else if (cloud1Position.X < -cloud1Texture.Width * 2.0f)
  256. cloud1Position.X = ScreenManager.GraphicsDevice.Viewport.Width;
  257. cloud2Position += new Vector2(16.0f, 0.0f) * elapsedTime *
  258. windDirection * wind.Y;
  259. if (cloud2Position.X > ScreenManager.GraphicsDevice.Viewport.Width)
  260. cloud2Position.X = -cloud2Texture.Width * 2.0f;
  261. else if (cloud2Position.X < -cloud2Texture.Width * 2.0f)
  262. cloud2Position.X = ScreenManager.GraphicsDevice.Viewport.Width;
  263. }
  264. #endregion
  265. #region Draw Helpers
  266. /// <summary>
  267. /// Draws the player's catapult
  268. /// </summary>
  269. void DrawPlayer(GameTime gameTime)
  270. {
  271. if (!gameOver)
  272. player.Draw(gameTime);
  273. }
  274. /// <summary>
  275. /// Draws the AI's catapult
  276. /// </summary>
  277. void DrawComputer(GameTime gameTime)
  278. {
  279. if (!gameOver)
  280. computer.Draw(gameTime);
  281. }
  282. /// <summary>
  283. /// Draw the sky, clouds, mountains, etc.
  284. /// </summary>
  285. private void DrawBackground()
  286. {
  287. // Clear the background
  288. ScreenManager.Game.GraphicsDevice.Clear(Color.White);
  289. // Draw the Sky
  290. ScreenManager.SpriteBatch.Draw(skyTexture, Vector2.Zero, Color.White);
  291. // Draw Cloud #1
  292. ScreenManager.SpriteBatch.Draw(cloud1Texture,
  293. cloud1Position, Color.White);
  294. // Draw the Mountain
  295. ScreenManager.SpriteBatch.Draw(mountainTexture,
  296. Vector2.Zero, Color.White);
  297. // Draw Cloud #2
  298. ScreenManager.SpriteBatch.Draw(cloud2Texture,
  299. cloud2Position, Color.White);
  300. // Draw the Castle, trees, and foreground
  301. ScreenManager.SpriteBatch.Draw(foregroundTexture,
  302. Vector2.Zero, Color.White);
  303. }
  304. /// <summary>
  305. /// Draw the HUD, which consists of the score elements and the GAME OVER tag.
  306. /// </summary>
  307. void DrawHud()
  308. {
  309. if (gameOver)
  310. {
  311. Texture2D texture;
  312. if (player.Score > computer.Score)
  313. {
  314. texture = victoryTexture;
  315. }
  316. else
  317. {
  318. texture = defeatTexture;
  319. }
  320. ScreenManager.SpriteBatch.Draw(
  321. texture,
  322. new Vector2(ScreenManager.Game.GraphicsDevice.Viewport.Width / 2 - texture.Width / 2,
  323. ScreenManager.Game.GraphicsDevice.Viewport.Height / 2 - texture.Height / 2),
  324. Color.White);
  325. }
  326. else
  327. {
  328. // Draw Player Hud
  329. ScreenManager.SpriteBatch.Draw(hudBackgroundTexture,
  330. playerHUDPosition, Color.White);
  331. ScreenManager.SpriteBatch.Draw(ammoTypeTexture,
  332. playerHUDPosition + new Vector2(33, 35), Color.White);
  333. DrawString(hudFont, player.Score.ToString(),
  334. playerHUDPosition + new Vector2(123, 35), Color.White);
  335. DrawString(hudFont, player.Name,
  336. playerHUDPosition + new Vector2(40, 1), Color.Blue);
  337. // Draw Computer Hud
  338. ScreenManager.SpriteBatch.Draw(hudBackgroundTexture,
  339. computerHUDPosition, Color.White);
  340. ScreenManager.SpriteBatch.Draw(ammoTypeTexture,
  341. computerHUDPosition + new Vector2(33, 35), Color.White);
  342. DrawString(hudFont, computer.Score.ToString(),
  343. computerHUDPosition + new Vector2(123, 35), Color.White);
  344. DrawString(hudFont, computer.Name,
  345. computerHUDPosition + new Vector2(40, 1), Color.Red);
  346. // Draw Wind direction
  347. string text = "WIND";
  348. Vector2 size = hudFont.MeasureString(text);
  349. Vector2 windarrowScale = new Vector2(wind.Y / 10, 1);
  350. ScreenManager.SpriteBatch.Draw(windArrowTexture,
  351. windArrowPosition, null, Color.White, 0, Vector2.Zero,
  352. windarrowScale, wind.X > 0
  353. ? SpriteEffects.None : SpriteEffects.FlipHorizontally, 0);
  354. DrawString(hudFont, text,
  355. windArrowPosition - new Vector2(0, size.Y), Color.Black);
  356. if (wind.Y == 0)
  357. {
  358. text = "NONE";
  359. DrawString(hudFont, text, windArrowPosition, Color.Black);
  360. }
  361. if (isHumanTurn)
  362. {
  363. // Prepare human prompt message
  364. text = !isDragging ?
  365. "Drag Anywhere to Fire" : "Release to Fire!";
  366. size = hudFont.MeasureString(text);
  367. }
  368. else
  369. {
  370. // Prepare AI message
  371. text = "I'll get you yet!";
  372. size = hudFont.MeasureString(text);
  373. }
  374. DrawString(hudFont, text,
  375. new Vector2(
  376. ScreenManager.GraphicsDevice.Viewport.Width / 2 - size.X / 2,
  377. ScreenManager.GraphicsDevice.Viewport.Height - size.Y),
  378. Color.Green);
  379. }
  380. }
  381. /// <summary>
  382. /// A simple helper to draw shadowed text.
  383. /// </summary>
  384. void DrawString(SpriteFont font, string text, Vector2 position, Color color)
  385. {
  386. ScreenManager.SpriteBatch.DrawString(font, text,
  387. new Vector2(position.X + 1, position.Y + 1), Color.Black);
  388. ScreenManager.SpriteBatch.DrawString(font, text, position, color);
  389. }
  390. /// <summary>
  391. /// A simple helper to draw shadowed text.
  392. /// </summary>
  393. void DrawString(SpriteFont font, string text, Vector2 position, Color color, float fontScale)
  394. {
  395. ScreenManager.SpriteBatch.DrawString(font, text, new Vector2(position.X + 1,
  396. position.Y + 1), Color.Black, 0, new Vector2(0, font.LineSpacing / 2),
  397. fontScale, SpriteEffects.None, 0);
  398. ScreenManager.SpriteBatch.DrawString(font, text, position, color, 0,
  399. new Vector2(0, font.LineSpacing / 2), fontScale, SpriteEffects.None, 0);
  400. }
  401. #endregion
  402. #region Input Helpers
  403. /// <summary>
  404. /// Finish the current game
  405. /// </summary>
  406. private void FinishCurrentGame()
  407. {
  408. ExitScreen();
  409. }
  410. /// <summary>
  411. /// Pause the current game
  412. /// </summary>
  413. private void PauseCurrentGame()
  414. {
  415. var pauseMenuBackground = new BackgroundScreen();
  416. if (isDragging)
  417. {
  418. isDragging = false;
  419. player.Catapult.CurrentState = CatapultState.Idle;
  420. }
  421. ScreenManager.AddScreen(pauseMenuBackground, null);
  422. ScreenManager.AddScreen(new PauseScreen(pauseMenuBackground,
  423. player, computer), null);
  424. }
  425. #endregion
  426. #region Gameplay Helpers
  427. /// <summary>
  428. /// Starts a new game session, setting all game states to initial values.
  429. /// </summary>
  430. void Start()
  431. {
  432. // Set initial wind direction
  433. wind = Vector2.Zero;
  434. isHumanTurn = false;
  435. changeTurn = true;
  436. computer.Catapult.CurrentState = CatapultState.Reset;
  437. }
  438. #endregion
  439. }
  440. }