NetworkBusyScreen.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // NetworkBusyScreen.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 Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Content;
  13. using Microsoft.Xna.Framework.Graphics;
  14. using GameStateManagement;
  15. #endregion
  16. namespace CatapultGame
  17. {
  18. /// <summary>
  19. /// When an asynchronous network operation (for instance searching for or joining a
  20. /// session) is in progress, we want to display some sort of busy indicator to let
  21. /// the user know the game hasn't just locked up. We also want to make sure they
  22. /// can't pick some other menu option before the current operation has finished.
  23. /// This screen takes care of both requirements in a single stroke. It monitors
  24. /// the IAsyncResult returned by an asynchronous network call, displaying a busy
  25. /// indicator for as long as the call is still in progress. When it notices the
  26. /// IAsyncResult has completed, it raises an event to let the game know it should
  27. /// proceed to the next step, after which the busy screen automatically goes away.
  28. /// Because this screen is on top of all others for as long as the asynchronous
  29. /// operation is in progress, it automatically takes over all user input,
  30. /// preventing any other menu entries being selected until the operation completes.
  31. /// </summary>
  32. class NetworkBusyScreen : GameScreen
  33. {
  34. #region Fields
  35. IAsyncResult asyncResult;
  36. Texture2D gradientTexture;
  37. Texture2D catTexture;
  38. #endregion
  39. #region Events
  40. public event EventHandler<OperationCompletedEventArgs> OperationCompleted;
  41. #endregion
  42. #region Initialization
  43. /// <summary>
  44. /// Constructs a network busy screen for the specified asynchronous operation.
  45. /// </summary>
  46. public NetworkBusyScreen (IAsyncResult asyncResult)
  47. {
  48. this.asyncResult = asyncResult;
  49. IsPopup = true;
  50. TransitionOnTime = TimeSpan.FromSeconds (0.1);
  51. TransitionOffTime = TimeSpan.FromSeconds (0.2);
  52. }
  53. /// <summary>
  54. /// Loads graphics content for this screen. This uses the shared ContentManager
  55. /// provided by the Game class, so the content will remain loaded forever.
  56. /// Whenever a subsequent NetworkBusyScreen tries to load this same content,
  57. /// it will just get back another reference to the already loaded data.
  58. /// </summary>
  59. public override void LoadContent ()
  60. {
  61. ContentManager content = ScreenManager.Game.Content;
  62. gradientTexture = content.Load<Texture2D> ("gradient");
  63. catTexture = content.Load<Texture2D> ("cat");
  64. }
  65. #endregion
  66. #region Update and Draw
  67. /// <summary>
  68. /// Updates the NetworkBusyScreen.
  69. /// </summary>
  70. public override void Update (GameTime gameTime, bool otherScreenHasFocus,
  71. bool coveredByOtherScreen)
  72. {
  73. base.Update (gameTime, otherScreenHasFocus, coveredByOtherScreen);
  74. // Has our asynchronous operation completed?
  75. if ((asyncResult != null) && asyncResult.IsCompleted) {
  76. // If so, raise the OperationCompleted event.
  77. if (OperationCompleted != null) {
  78. OperationCompleted (this,
  79. new OperationCompletedEventArgs (asyncResult));
  80. }
  81. ExitScreen ();
  82. asyncResult = null;
  83. }
  84. }
  85. /// <summary>
  86. /// Draws the NetworkBusyScreen.
  87. /// </summary>
  88. public override void Draw (GameTime gameTime)
  89. {
  90. SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
  91. SpriteFont font = ScreenManager.Font;
  92. string message = Resources.NetworkBusy;
  93. const int hPad = 32 ;
  94. const int vPad = 16 ;
  95. // Center the message text in the viewport.
  96. Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
  97. Vector2 viewportSize = new Vector2 (viewport.Width, viewport.Height);
  98. Vector2 textSize = font.MeasureString (message);
  99. // Add enough room to spin a cat.
  100. Vector2 catSize = new Vector2 (catTexture.Width);
  101. textSize.X = Math.Max (textSize.X, catSize.X);
  102. textSize.Y += catSize.Y + vPad;
  103. Vector2 textPosition = (viewportSize - textSize) / 2;
  104. // The background includes a border somewhat larger than the text itself.
  105. Rectangle backgroundRectangle = new Rectangle ((int)textPosition.X - hPad,
  106. (int)textPosition.Y - vPad,
  107. (int)textSize.X + hPad * 2,
  108. (int)textSize.Y + vPad * 2);
  109. // Fade the popup alpha during transitions.
  110. Color color = Color.White * TransitionAlpha;
  111. spriteBatch.Begin ();
  112. // Draw the background rectangle.
  113. spriteBatch.Draw (gradientTexture, backgroundRectangle, color);
  114. // Draw the message box text.
  115. spriteBatch.DrawString (font, message, textPosition, color);
  116. // Draw the spinning cat progress indicator.
  117. float catRotation = (float)gameTime.TotalGameTime.TotalSeconds * 3;
  118. Vector2 catPosition = new Vector2 (textPosition.X + textSize.X / 2,
  119. textPosition.Y + textSize.Y -
  120. catSize.Y / 2);
  121. spriteBatch.Draw (catTexture, catPosition, null, color, catRotation,
  122. catSize / 2, 1, SpriteEffects.None, 0);
  123. spriteBatch.End ();
  124. }
  125. #endregion
  126. }
  127. }