using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using RecrownedAthenaeum.Camera; using System.Collections.Generic; namespace RecrownedAthenaeum.ScreenSystem { public enum ScreenState { EnterTransition, ExitTransition, Normal } public class Screen { public List Transitions; public bool UseRenderTargetForExitTransition; public Color BackgroundColor; public GraphicsDevice GraphicsDevice { get; private set; } public Screen NextScreen { get; set; } public Rectangle ScreenSize { get; private set; } public bool Initiated { get; private set; } public Camera2D Camera { get; private set; } public Screen(bool useEnterTransition = false) { State = useEnterTransition ? ScreenState.EnterTransition : ScreenState.Normal; Transitions = new List(); } /// /// Called only once after initialization to give required parameters. /// public virtual void Initiate(GraphicsDevice graphicsDevice, Rectangle screenSize, Camera2D camera) { this.Camera = camera; this.ScreenSize = screenSize; GraphicsDevice = graphicsDevice; Initiated = true; } /// /// Called to update the screen. /// /// Game time information. public virtual void Update(GameTime gameTime) { } /// /// Called to draw this screen. /// /// SpriteBatch to use. public virtual void Draw(SpriteBatch spriteBatch) { foreach (ITransition transition in Transitions) { transition.DrawTransition(spriteBatch); } } /// /// Updates the transition based on the current state of the screen. /// /// Time passed since last frame in seconds. /// If the this transition should wait. /// The previous screen's frame. May be null. /// Only returns true if exit transition is complete. Returns false otherwise. public bool UpdateTransition(double delta, bool waiting) { switch (State) { case ScreenState.EnterTransition: EnteringTransition(delta, waiting); break; case ScreenState.ExitTransition: return ExitingTransition(delta, waiting); } return false; } private void EnteringTransition(double delta, bool waiting) { bool complete = true; for (int transitionID = 0; transitionID < Transitions.Count; transitionID++) { ITransition transition = Transitions[transitionID]; if (!transition.EnteringTransition(delta, waiting)) { complete = false; } } if (complete && State != ScreenState.ExitTransition) { State = ScreenState.Normal; } } private bool ExitingTransition(double delta, bool waiting) { bool complete = true; foreach (ITransition transition in Transitions) { if (!transition.ExitingTransition(delta, waiting)) { complete = false; } } return complete; } /// /// Called when the screen is shown. /// public virtual void Show() { foreach (ITransition transition in Transitions) { transition.InitiateTransition(ScreenSize); } } /// /// Called when this screen is no longer the displayed screen. /// public virtual void Hide() { } /// /// Called whenever the status of assets changes from being loaded to unloaded or unloaded to loaded. /// /// True for loaded, false for unloaded. public virtual void AssetLoadStateChange(bool state) { } public ScreenState State { get; private set; } /// /// Call this to begin exit transition. /// /// Whether or not to use a render target for the next screen to use. public void StartExitTransition(bool UseRenderTargetForExitTransition = false) { this.UseRenderTargetForExitTransition = UseRenderTargetForExitTransition; State = ScreenState.ExitTransition; } /// /// Called everytime the previous screen frame buffer updates. Used for transition purposes. /// /// The previous screen's render buffer. public virtual void UpdatePreviousScreenFrame(RenderTarget2D previousScreenFrame) { foreach (ITransition transition in Transitions) { transition.UpdatePreviousScreenFrame(previousScreenFrame); } } } }