GameplayScreen.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  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. //using Microsoft.Xna.Framework.Net; // Not available in MonoGame 3.8
  21. namespace CatapultGame
  22. {
  23. class GameplayScreen : GameScreen
  24. {
  25. enum MessageType : byte
  26. {
  27. NewGame = 1,
  28. CatapultFiring = 2,
  29. CatapultAiming = 3,
  30. UpdateEnvironment = 4,
  31. }
  32. // internal NetworkSession NetworkSession { get; private set; } // Not available in MonoGame 3.8
  33. // PacketReader packetReader = new PacketReader (); // Not available in MonoGame 3.8
  34. // PacketWriter packetWriter = new PacketWriter (); // Not available in MonoGame 3.8
  35. internal bool IsNetworking { get; private set; }
  36. // Texture Members
  37. Texture2D foregroundTexture;
  38. Texture2D cloud1Texture;
  39. Texture2D cloud2Texture;
  40. Texture2D mountainTexture;
  41. Texture2D skyTexture;
  42. Texture2D hudBackgroundTexture;
  43. Texture2D ammoTypeTexture;
  44. Texture2D windArrowTexture;
  45. Texture2D defeatTexture;
  46. Texture2D victoryTexture;
  47. SpriteFont hudFont;
  48. // Rendering members
  49. Vector2 cloud1Position;
  50. Vector2 cloud2Position;
  51. Vector2 playerOneHUDPosition;
  52. Vector2 computerHUDPosition;
  53. Vector2 windArrowPosition;
  54. // Gameplay members
  55. Human playerOne;
  56. Human playerTwo;
  57. Vector2 wind;
  58. bool changeTurn;
  59. bool isFirstPlayerTurn;
  60. bool gameOver;
  61. Random random;
  62. const int minWind = 0;
  63. const int maxWind = 10;
  64. // Helper members
  65. bool isDragging;
  66. public GameplayScreen ()
  67. {
  68. EnabledGestures = GestureType.FreeDrag |
  69. GestureType.DragComplete |
  70. GestureType.Tap;
  71. random = new Random ();
  72. }
  73. /// <summary>
  74. /// Loads the game assets and initializes "players"
  75. /// </summary>
  76. public override void LoadContent ()
  77. {
  78. base.LoadContent ();
  79. #if ANDROID || IPHONE || LINUX || WINDOWS
  80. LoadAssets();
  81. #endif
  82. // Start the game
  83. Start ();
  84. }
  85. public void LoadAssets ()
  86. {
  87. // NetworkSession = ScreenManager.Game.Services.GetService (typeof(NetworkSession)) as NetworkSession; // Not available in MonoGame 3.8
  88. // IsNetworking = NetworkSession != null; // Not available in MonoGame 3.8
  89. IsNetworking = false; // Disable networking for MonoGame 3.8
  90. // Load textures
  91. foregroundTexture = Load<Texture2D> ("Textures/Backgrounds/gameplay_screen");
  92. cloud1Texture = Load<Texture2D> ("Textures/Backgrounds/cloud1");
  93. cloud2Texture = Load<Texture2D> ("Textures/Backgrounds/cloud2");
  94. mountainTexture = Load<Texture2D> ("Textures/Backgrounds/mountain");
  95. skyTexture = Load<Texture2D> ("Textures/Backgrounds/sky");
  96. defeatTexture = Load<Texture2D> ("Textures/Backgrounds/defeat");
  97. victoryTexture = Load<Texture2D> ("Textures/Backgrounds/victory");
  98. hudBackgroundTexture = Load<Texture2D> ("Textures/HUD/hudBackground");
  99. windArrowTexture = Load<Texture2D> ("Textures/HUD/windArrow");
  100. ammoTypeTexture = Load<Texture2D> ("Textures/HUD/ammoType");
  101. // Load font
  102. hudFont = Load<SpriteFont> ("Fonts/HUDFont");
  103. // Define initial cloud position
  104. cloud1Position = new Vector2 (224 - cloud1Texture.Width, 32);
  105. cloud2Position = new Vector2 (64, 90);
  106. // Define initial HUD positions
  107. playerOneHUDPosition = new Vector2 (7, 7);
  108. computerHUDPosition = new Vector2 (613, 7);
  109. windArrowPosition = new Vector2 (345, 46);
  110. // Initialize human & other players
  111. if (IsNetworking) {
  112. // Networking code disabled in MonoGame 3.8
  113. // Set up default single player game instead
  114. playerOne = new Human (ScreenManager.Game, ScreenManager.SpriteBatch, PlayerSide.Left);
  115. playerOne.Initialize ();
  116. playerOne.Name = "Player 1";
  117. playerTwo = new AI (ScreenManager.Game, ScreenManager.SpriteBatch);
  118. playerTwo.Initialize ();
  119. playerTwo.Name = "Player 2";
  120. } else {
  121. playerOne = new Human (ScreenManager.Game, ScreenManager.SpriteBatch, PlayerSide.Left);
  122. playerOne.Initialize ();
  123. playerOne.Name = "Player 1";
  124. playerTwo = new AI (ScreenManager.Game, ScreenManager.SpriteBatch);
  125. playerTwo.Initialize ();
  126. playerTwo.Name = "Player 2";
  127. }
  128. // Identify enemies playerOne.Enemy = playerTwo;
  129. playerTwo.Enemy = playerOne;
  130. }
  131. /// <summary>
  132. /// Runs one frame of update for the game.
  133. /// </summary>
  134. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  135. public override void Update (GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
  136. {
  137. float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
  138. // Check it one of the players reached 5 and stop the game
  139. if ((playerOne.Catapult.GameOver || playerTwo.Catapult.GameOver) &&
  140. (gameOver == false)) {
  141. gameOver = true;
  142. if (IsNetworking) {
  143. // if (NetworkSession.IsHost) { // Not available in MonoGame 3.8
  144. // if (playerOne.Score > playerTwo.Score) {
  145. // AudioManager.PlaySound ("gameOver_Win");
  146. // } else {
  147. // AudioManager.PlaySound ("gameOver_Lose");
  148. // }
  149. // }
  150. // else {
  151. // if (playerOne.Score > playerTwo.Score) {
  152. // AudioManager.PlaySound ("gameOver_Lose");
  153. // } else {
  154. // AudioManager.PlaySound ("gameOver_Win");
  155. // }
  156. // }
  157. // Simple fallback - play win sound for player 1 if they have higher score
  158. if (playerOne.Score > playerTwo.Score) {
  159. AudioManager.PlaySound ("gameOver_Win");
  160. } else {
  161. AudioManager.PlaySound ("gameOver_Lose");
  162. }
  163. }
  164. else {
  165. if (playerOne.Score > playerTwo.Score) {
  166. AudioManager.PlaySound ("gameOver_Win");
  167. } else {
  168. AudioManager.PlaySound ("gameOver_Lose");
  169. }
  170. }
  171. return;
  172. }
  173. // If Reset flag raised and both catapults are not animating -
  174. // active catapult finished the cycle, new turn!
  175. if ((playerOne.Catapult.CurrentState == CatapultState.Reset ||
  176. playerTwo.Catapult.CurrentState == CatapultState.Reset) &&
  177. !(playerOne.Catapult.AnimationRunning ||
  178. playerTwo.Catapult.AnimationRunning)) {
  179. changeTurn = true;
  180. if (playerOne.IsActive == true) { //Last turn was a human turn?
  181. playerOne.IsActive = false;
  182. playerTwo.IsActive = true;
  183. isFirstPlayerTurn = false;
  184. playerOne.Catapult.CurrentState = CatapultState.Idle;
  185. if (playerTwo.IsAI)
  186. playerTwo.Catapult.CurrentState = CatapultState.Aiming;
  187. else
  188. playerTwo.Catapult.CurrentState = CatapultState.Idle;
  189. } else { //It was an AI turn
  190. playerOne.IsActive = true;
  191. playerTwo.IsActive = false;
  192. isFirstPlayerTurn = true;
  193. playerTwo.Catapult.CurrentState = CatapultState.Idle;
  194. playerOne.Catapult.CurrentState = CatapultState.Idle;
  195. }
  196. }
  197. if (changeTurn) {
  198. // Update wind
  199. wind = new Vector2 (random.Next (-1, 2), random.Next (minWind, maxWind + 1));
  200. // Set new wind value to the players and
  201. playerOne.Catapult.Wind = playerTwo.Catapult.Wind = wind.X > 0 ? wind.Y : -wind.Y;
  202. changeTurn = false;
  203. }
  204. // Update the players
  205. playerOne.Update (gameTime);
  206. playerTwo.Update (gameTime);
  207. // Updates the clouds position
  208. UpdateClouds (elapsed);
  209. // UpdateNetworkSession (); // Disabled - networking not available in MonoGame 3.8
  210. base.Update (gameTime, otherScreenHasFocus, coveredByOtherScreen);
  211. }
  212. /// <summary>
  213. /// Draw the game world, effects, and HUD
  214. /// </summary>
  215. /// <param name="gameTime">The elapsed time since last Draw</param>
  216. public override void Draw (GameTime gameTime)
  217. {
  218. ScreenManager.SpriteBatch.Begin ();
  219. // Render all parts of the screen
  220. DrawBackground ();
  221. DrawComputer (gameTime);
  222. DrawPlayer (gameTime);
  223. DrawHud ();
  224. ScreenManager.SpriteBatch.End ();
  225. }
  226. /// <summary>
  227. /// Input helper method provided by GameScreen. Packages up the various input
  228. /// values for ease of use.
  229. /// </summary>
  230. /// <param name="input">The state of the gamepads</param>
  231. public override void HandleInput (InputState input)
  232. {
  233. if (input == null)
  234. throw new ArgumentNullException ("input");
  235. if (gameOver) {
  236. if (input.IsPauseGame (null)) {
  237. FinishCurrentGame ();
  238. }
  239. if (input.MouseGesture.HasFlag(MouseGestureType.LeftClick))
  240. FinishCurrentGame();
  241. foreach (GestureSample gestureSample in input.Gestures) {
  242. if (gestureSample.GestureType == GestureType.Tap) {
  243. FinishCurrentGame ();
  244. }
  245. }
  246. return;
  247. }
  248. // if (NetworkSession != null) { // Not available in MonoGame 3.8
  249. // if ((isFirstPlayerTurn && !NetworkSession.IsHost)
  250. // || (!isFirstPlayerTurn && NetworkSession.IsHost))
  251. // return;
  252. // }
  253. if (input.IsPauseGame (null)) {
  254. PauseCurrentGame ();
  255. } else if (isFirstPlayerTurn &&
  256. (playerOne.Catapult.CurrentState == CatapultState.Idle ||
  257. playerOne.Catapult.CurrentState == CatapultState.Aiming)) {
  258. // First we try with mouse input
  259. playerOne.HandleInput (input);
  260. isDragging = playerOne.isDragging;
  261. // Read all available gestures
  262. foreach (GestureSample gestureSample in input.Gestures) {
  263. if (gestureSample.GestureType == GestureType.FreeDrag)
  264. isDragging = true;
  265. else if (gestureSample.GestureType == GestureType.DragComplete)
  266. isDragging = false;
  267. playerOne.HandleInput (gestureSample);
  268. }
  269. } else if (!isFirstPlayerTurn &&
  270. (playerTwo.Catapult.CurrentState == CatapultState.Idle ||
  271. playerTwo.Catapult.CurrentState == CatapultState.Aiming)) {
  272. // First we try with mouse input
  273. playerTwo.HandleInput (input);
  274. isDragging = playerTwo.isDragging;
  275. // Read all available gestures
  276. foreach (GestureSample gestureSample in input.Gestures) {
  277. if (gestureSample.GestureType == GestureType.FreeDrag)
  278. isDragging = true;
  279. else if (gestureSample.GestureType == GestureType.DragComplete)
  280. isDragging = false;
  281. playerTwo.HandleInput (gestureSample);
  282. }
  283. }
  284. }
  285. /*
  286. // Networking methods disabled in MonoGame 3.8
  287. Vector3 catapultInfoVector = Vector3.Zero;
  288. void UpdateNetworkSession ()
  289. {
  290. if (NetworkSession == null)
  291. return;
  292. if (NetworkSession.IsHost) {
  293. packetWriter.Write((int)MessageType.UpdateEnvironment);
  294. packetWriter.Write(wind);
  295. packetWriter.Write(cloud1Position);
  296. packetWriter.Write(cloud2Position);
  297. // Update our locally controlled tanks, and send their
  298. // latest position data to everyone in the session.
  299. foreach (LocalNetworkGamer gamer in NetworkSession.LocalGamers) {
  300. gamer.SendData(packetWriter, SendDataOptions.ReliableInOrder);
  301. }
  302. }
  303. if (playerOne.Catapult.CurrentState == CatapultState.Aiming) {
  304. SendCatapultInfo(MessageType.CatapultAiming, playerOne);
  305. }
  306. if (playerOne.Catapult.CurrentState == CatapultState.Firing) {
  307. SendCatapultInfo(MessageType.CatapultFiring, playerOne);
  308. }
  309. if (playerTwo.Catapult.CurrentState == CatapultState.Aiming) {
  310. SendCatapultInfo(MessageType.CatapultAiming, playerTwo);
  311. }
  312. if (playerTwo.Catapult.CurrentState == CatapultState.Firing) {
  313. SendCatapultInfo(MessageType.CatapultFiring, playerTwo);
  314. }
  315. // Pump the underlying session object.
  316. NetworkSession.Update ();
  317. // Make sure the session has not ended.
  318. if (NetworkSession == null)
  319. return;
  320. // Read any packets
  321. foreach (LocalNetworkGamer gamer in NetworkSession.LocalGamers) {
  322. ReadIncomingPackets (gamer);
  323. }
  324. }
  325. void SendCatapultInfo (MessageType messageType, Human player)
  326. {
  327. packetWriter.Write((int)messageType);
  328. catapultInfoVector.X = player.Catapult.ShotStrength;
  329. catapultInfoVector.Y = player.Catapult.ShotVelocity;
  330. catapultInfoVector.Z = player.ArrowScale;
  331. packetWriter.Write(catapultInfoVector);
  332. // Update our locally controlled catapults, and send their
  333. // latest position data to everyone in the session.
  334. foreach (LocalNetworkGamer gamer in NetworkSession.LocalGamers) {
  335. gamer.SendData(packetWriter, SendDataOptions.ReliableInOrder);
  336. }
  337. }
  338. /// <summary>
  339. /// Helper for reading incoming network packets.
  340. /// </summary>
  341. void ReadIncomingPackets (LocalNetworkGamer gamer)
  342. {
  343. // Keep reading as long as incoming packets are available.
  344. while (gamer.IsDataAvailable) {
  345. NetworkGamer sender;
  346. // Read a single packet from the network.
  347. gamer.ReceiveData (packetReader, out sender);
  348. // Discard packets sent by local gamers: we already know their state!
  349. if (sender.IsLocal)
  350. continue;
  351. MessageType msgType = (MessageType)packetReader.ReadInt32 ();
  352. switch (msgType) {
  353. case MessageType.NewGame:
  354. //ReceiveNewNetworkedGame();
  355. break;
  356. case MessageType.CatapultAiming:
  357. if (isFirstPlayerTurn && !NetworkSession.IsHost) {
  358. playerOne.Catapult.CurrentState = CatapultState.Aiming;
  359. playerOne.isDragging = true;
  360. catapultInfoVector = packetReader.ReadVector3();
  361. playerOne.Catapult.ShotStrength = catapultInfoVector.X;
  362. playerOne.Catapult.ShotVelocity = catapultInfoVector.Y;
  363. playerOne.ArrowScale = catapultInfoVector.Z;
  364. }
  365. if (!isFirstPlayerTurn && NetworkSession.IsHost) {
  366. playerTwo.Catapult.CurrentState = CatapultState.Aiming;
  367. playerTwo.isDragging = true;
  368. catapultInfoVector = packetReader.ReadVector3();
  369. playerTwo.Catapult.ShotStrength = catapultInfoVector.X;
  370. playerTwo.Catapult.ShotVelocity = catapultInfoVector.Y;
  371. playerTwo.ArrowScale = catapultInfoVector.Z;
  372. }
  373. break;
  374. case MessageType.CatapultFiring:
  375. if (isFirstPlayerTurn && !NetworkSession.IsHost) {
  376. catapultInfoVector = packetReader.ReadVector3();
  377. playerOne.Catapult.Fire (catapultInfoVector.Y);
  378. playerOne.Catapult.CurrentState = CatapultState.Firing;
  379. playerOne.ResetDragState();
  380. }
  381. if (!isFirstPlayerTurn && NetworkSession.IsHost) {
  382. catapultInfoVector = packetReader.ReadVector3();
  383. playerTwo.Catapult.Fire (catapultInfoVector.Y);
  384. playerTwo.Catapult.CurrentState = CatapultState.Firing;
  385. playerTwo.ResetDragState();
  386. }
  387. break;
  388. case MessageType.UpdateEnvironment:
  389. wind = packetReader.ReadVector2();
  390. cloud1Position = packetReader.ReadVector2();
  391. cloud2Position = packetReader.ReadVector2();
  392. // Set new wind value to the players and
  393. playerOne.Catapult.Wind = playerTwo.Catapult.Wind = wind.X > 0 ? wind.Y : -wind.Y;
  394. break;
  395. }
  396. }
  397. }
  398. */
  399. // End networking methods
  400. private void UpdateClouds (float elapsedTime)
  401. {
  402. // Move the clouds according to the wind
  403. int windDirection = wind.X > 0 ? 1 : -1;
  404. cloud1Position += new Vector2 (24.0f, 0.0f) * elapsedTime *
  405. windDirection * wind.Y;
  406. if (cloud1Position.X > ScreenManager.GraphicsDevice.Viewport.Width)
  407. cloud1Position.X = -cloud1Texture.Width * 2.0f;
  408. else if (cloud1Position.X < -cloud1Texture.Width * 2.0f)
  409. cloud1Position.X = ScreenManager.GraphicsDevice.Viewport.Width;
  410. cloud2Position += new Vector2 (16.0f, 0.0f) * elapsedTime *
  411. windDirection * wind.Y;
  412. if (cloud2Position.X > ScreenManager.GraphicsDevice.Viewport.Width)
  413. cloud2Position.X = -cloud2Texture.Width * 2.0f;
  414. else if (cloud2Position.X < -cloud2Texture.Width * 2.0f)
  415. cloud2Position.X = ScreenManager.GraphicsDevice.Viewport.Width;
  416. }
  417. /// <summary>
  418. /// Draws the player's catapult
  419. /// </summary>
  420. void DrawPlayer (GameTime gameTime)
  421. {
  422. if (!gameOver)
  423. playerOne.Draw (gameTime);
  424. }
  425. /// <summary>
  426. /// Draws the AI's catapult
  427. /// </summary>
  428. void DrawComputer (GameTime gameTime)
  429. {
  430. if (!gameOver)
  431. playerTwo.Draw (gameTime);
  432. }
  433. /// <summary>
  434. /// Draw the sky, clouds, mountains, etc.
  435. /// </summary>
  436. private void DrawBackground ()
  437. {
  438. // Clear the background
  439. ScreenManager.Game.GraphicsDevice.Clear (Color.White);
  440. // Draw the Sky
  441. ScreenManager.SpriteBatch.Draw (skyTexture, Vector2.Zero, Color.White);
  442. // Draw Cloud #1
  443. ScreenManager.SpriteBatch.Draw (cloud1Texture,
  444. cloud1Position, Color.White);
  445. // Draw the Mountain
  446. ScreenManager.SpriteBatch.Draw (mountainTexture,
  447. Vector2.Zero, Color.White);
  448. // Draw Cloud #2
  449. ScreenManager.SpriteBatch.Draw (cloud2Texture,
  450. cloud2Position, Color.White);
  451. // Draw the Castle, trees, and foreground
  452. ScreenManager.SpriteBatch.Draw (foregroundTexture,
  453. Vector2.Zero, Color.White);
  454. }
  455. /// <summary>
  456. /// Draw the HUD, which consists of the score elements and the GAME OVER tag.
  457. /// </summary>
  458. void DrawHud ()
  459. {
  460. if (gameOver) {
  461. Texture2D texture; if (IsNetworking) {
  462. // if (NetworkSession.IsHost) { // Not available in MonoGame 3.8
  463. // if (playerOne.Score > playerTwo.Score) {
  464. // texture = victoryTexture;
  465. // } else {
  466. // texture = defeatTexture;
  467. // }
  468. // }
  469. // else {
  470. // if (playerOne.Score > playerTwo.Score) {
  471. // texture = defeatTexture;
  472. // } else {
  473. // texture = victoryTexture;
  474. // }
  475. // }
  476. // Simple fallback - show victory for player 1 if they have higher score
  477. if (playerOne.Score > playerTwo.Score) {
  478. texture = victoryTexture;
  479. } else {
  480. texture = defeatTexture;
  481. }
  482. }
  483. else {
  484. if (playerOne.Score > playerTwo.Score) {
  485. texture = victoryTexture;
  486. } else {
  487. texture = defeatTexture;
  488. }
  489. }
  490. ScreenManager.SpriteBatch.Draw (texture,
  491. new Vector2 (ScreenManager.Game.GraphicsDevice.Viewport.Width / 2 - texture.Width / 2,
  492. ScreenManager.Game.GraphicsDevice.Viewport.Height / 2 - texture.Height / 2),
  493. Color.White);
  494. } else {
  495. // Draw Player Hud
  496. ScreenManager.SpriteBatch.Draw (hudBackgroundTexture, playerOneHUDPosition, Color.White);
  497. ScreenManager.SpriteBatch.Draw (ammoTypeTexture, playerOneHUDPosition + new Vector2 (33, 35), Color.White);
  498. DrawString (hudFont, playerOne.Score.ToString (), playerOneHUDPosition + new Vector2 (123, 35), Color.White);
  499. DrawString (hudFont, playerOne.Name, playerOneHUDPosition + new Vector2 (40, 1), Color.Blue);
  500. // Draw Computer Hud
  501. ScreenManager.SpriteBatch.Draw (hudBackgroundTexture, computerHUDPosition, Color.White);
  502. ScreenManager.SpriteBatch.Draw (ammoTypeTexture, computerHUDPosition + new Vector2 (33, 35), Color.White);
  503. DrawString (hudFont, playerTwo.Score.ToString (), computerHUDPosition + new Vector2 (123, 35), Color.White);
  504. DrawString (hudFont, playerTwo.Name, computerHUDPosition + new Vector2 (40, 1), Color.Red);
  505. // Draw Wind direction
  506. string text = "WIND";
  507. Vector2 size = hudFont.MeasureString (text);
  508. Vector2 windarrowScale = new Vector2 (wind.Y / 10, 1);
  509. ScreenManager.SpriteBatch.Draw (windArrowTexture,
  510. windArrowPosition, null, Color.White, 0, Vector2.Zero,
  511. windarrowScale, wind.X > 0 ? SpriteEffects.None : SpriteEffects.FlipHorizontally, 0);
  512. DrawString (hudFont, text, windArrowPosition - new Vector2 (0, size.Y), Color.Black);
  513. if (wind.Y == 0) {
  514. text = "NONE";
  515. DrawString (hudFont, text, windArrowPosition, Color.Black);
  516. }
  517. if (IsNetworking) {
  518. if (isFirstPlayerTurn) {
  519. // if (NetworkSession.IsHost) { // Not available in MonoGame 3.8
  520. // // Prepare player one prompt message
  521. // text = !isDragging ? "Drag Anywhere to Fire" : "Release to Fire!";
  522. // }
  523. // else {
  524. // text = "Waiting for " + playerOne.Name;
  525. // }
  526. // Simple fallback - assume player 1 is local
  527. text = !isDragging ? "Drag Anywhere to Fire" : "Release to Fire!";
  528. } else {
  529. // if (NetworkSession.IsHost) { // Not available in MonoGame 3.8
  530. // // Prepare player one prompt message
  531. // text = "Waiting for " + playerTwo.Name;
  532. // }
  533. // else {
  534. // text = !isDragging ? "Drag Anywhere to Fire" : "Release to Fire!";
  535. // }
  536. // Simple fallback - assume player 2 is local
  537. text = !isDragging ? "Drag Anywhere to Fire" : "Release to Fire!";
  538. }
  539. }
  540. else {
  541. if (isFirstPlayerTurn) {
  542. // Prepare player one prompt message
  543. text = !isDragging ? "Drag Anywhere to Fire" : "Release to Fire!";
  544. } else {
  545. // Prepare other player message
  546. text = "I'll get you yet!";
  547. }
  548. }
  549. size = hudFont.MeasureString (text);
  550. DrawString (hudFont, text,
  551. new Vector2 (ScreenManager.GraphicsDevice.Viewport.Width / 2 - size.X / 2,
  552. ScreenManager.GraphicsDevice.Viewport.Height - size.Y),
  553. Color.Green);
  554. }
  555. }
  556. /// <summary>
  557. /// A simple helper to draw shadowed text.
  558. /// </summary>
  559. void DrawString (SpriteFont font, string text, Vector2 position, Color color)
  560. {
  561. ScreenManager.SpriteBatch.DrawString (font, text,
  562. new Vector2 (position.X + 1, position.Y + 1), Color.Black);
  563. ScreenManager.SpriteBatch.DrawString (font, text, position, color);
  564. }
  565. /// <summary>
  566. /// A simple helper to draw shadowed text.
  567. /// </summary>
  568. void DrawString (SpriteFont font, string text, Vector2 position, Color color, float fontScale)
  569. {
  570. ScreenManager.SpriteBatch.DrawString (font, text, new Vector2 (position.X + 1,
  571. position.Y + 1), Color.Black, 0, new Vector2 (0, font.LineSpacing / 2),
  572. fontScale, SpriteEffects.None, 0);
  573. ScreenManager.SpriteBatch.DrawString (font, text, position, color, 0,
  574. new Vector2 (0, font.LineSpacing / 2), fontScale, SpriteEffects.None, 0);
  575. }
  576. /// <summary>
  577. /// Finish the current game
  578. /// </summary>
  579. private void FinishCurrentGame ()
  580. {
  581. ExitScreen ();
  582. }
  583. /// <summary>
  584. /// Pause the current game
  585. /// </summary>
  586. private void PauseCurrentGame ()
  587. {
  588. var pauseMenuBackground = new BackgroundScreen ();
  589. if (isDragging) {
  590. isDragging = false;
  591. playerOne.Catapult.CurrentState = CatapultState.Idle;
  592. }
  593. ScreenManager.AddScreen (pauseMenuBackground, null);
  594. ScreenManager.AddScreen (new PauseScreen (pauseMenuBackground, playerOne, playerTwo), null);
  595. }
  596. /// <summary>
  597. /// Starts a new game session, setting all game states to initial values.
  598. /// </summary>
  599. void Start ()
  600. {
  601. // Set initial wind direction
  602. wind = Vector2.Zero;
  603. isFirstPlayerTurn = false;
  604. changeTurn = true;
  605. playerTwo.Catapult.CurrentState = CatapultState.Reset;
  606. }
  607. }
  608. }