GameplayScreen.cs 17 KB

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