using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using RecrownedAthenaeum.Graphics.Render; using System; namespace RecrownedAthenaeum.UI.ScreenSystem { /// /// A screen specifically meant to fill in loading times. /// public class LoadingScreen : Screen, ITransition { private const float ENTER_TIME = 2f; private const float EXIT_TIME = 1f; Game game; readonly Texture2D texture; Color color; Rectangle textureBounds; readonly float proportion; bool recorded; float rR, rG, rB; float progR, progG, progB; float progC = 254; float rotation; readonly bool rotate; Vector2 origin; /// /// Constructs a loading screen. /// /// The game itself to adjust mouse settings and such. /// /// /// public LoadingScreen(Game game, Texture2D screenImage, float proportion, bool rotate = false) : base(true) { this.game = game; this.texture = screenImage; this.proportion = proportion; this.rotate = rotate; Transitions.Add(this); } /// public override void Show() { game.IsMouseVisible = false; base.Show(); } /// public override void Hide() { game.IsMouseVisible = true; base.Hide(); } /// /// Sets things to correct values for start of transition. /// /// The window dimensions. public void InitiateTransition(Rectangle dimensions) { color = Color.White; textureBounds.Width = (int)(height * proportion); textureBounds.Height = (int)(height * proportion); textureBounds.X = (width) / 2; textureBounds.Y = (height) / 2; origin.X = texture.Width / 2f; origin.Y = texture.Height / 2f; } void DoRotate(float deltaf) { rotation += (2f / 3f) * (float)Math.PI * deltaf; if (rotation >= 2 * Math.PI) { rotation = 0; } } /// /// Draws the transition. /// /// Batch to use. public void DrawTransition(ConsistentSpriteBatch spriteBatch) { spriteBatch.Draw(texture, textureBounds, null, color, rotation, origin, SpriteEffects.None, 0f); } /// /// Updates the entering transition. /// /// Time passed between frames. /// Whether or not this transition should be waiting. /// Whether or not transition is complete. public bool UpdateEnteringTransition(double delta, bool waiting) { float deltaf = (float)delta; if (rotate) { DoRotate(deltaf); } if (waiting) { if (progR < 254 || progG < 254 || progB < 254) { if (!recorded) { rR = (Color.White.R - BackgroundColor.R) / ENTER_TIME; rG = (Color.White.G - BackgroundColor.G) / ENTER_TIME; rB = (Color.White.B - BackgroundColor.B) / ENTER_TIME; recorded = true; } progR += rR * deltaf; progR = Math.Min(progR, 254); progG += rG * deltaf; progG = Math.Min(progG, 254); progB += rB * deltaf; progB = Math.Min(progB, 254); BackgroundColor.R = (byte)progR; BackgroundColor.G = (byte)progG; BackgroundColor.B = (byte)progB; } else { StartExitTransition(true); return true; } } return false; } /// /// Updates the exiting transition. /// /// Time passed between frames. /// Whether or not this transition should be waiting. /// Whether or not transition is complete. public bool UpdateExitingTransition(double delta, bool waiting) { float deltaf = (float)delta; if (rotate) { DoRotate(deltaf); } if (progC > 0) { float rate = deltaf * 255 / EXIT_TIME; progC -= rate; progC = Math.Max(progC, 0); color.R = (byte)progC; color.G = (byte)progC; color.B = (byte)progC; color.A = (byte)progC; } else { return true; } return false; } } }