GameplayScreen.cs 18 KB

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