added screen manager to utilities

This commit is contained in:
Harrison Deng 2018-11-12 19:40:27 -06:00
parent 51f13b1578
commit d8bb78252d
4 changed files with 150 additions and 80 deletions

View File

@ -55,6 +55,7 @@
<Compile Include="Zer01HD\Utilities\Input\InputListener.cs" />
<Compile Include="Zer01HD\Utilities\Input\InputUtilities.cs" />
<Compile Include="Zer01HD\Utilities\Persistence\Preferences.cs" />
<Compile Include="Zer01HD\Utilities\ScreenSystem\ScreenManager.cs" />
<Compile Include="Zer01HD\Utilities\UI\Interactive\BasicButton.cs" />
<Compile Include="Zer01HD\Utilities\ScreenSystem\ITransition.cs" />
<Compile Include="Zer01HD\Utilities\ScreenSystem\LoadingScreen.cs" />

View File

@ -29,37 +29,9 @@ namespace RhythmBullet
public readonly ContentSystem Assets;
readonly ResolutionContentResolver resolutionContentResolver;
public PreferencesManager preferencesManager;
private Screen previousScreen;
private RenderTarget2D previousScreenRenderTarget;
private Screen currentScreen;
private bool resizing;
private ScreenManager screenManager;
private Camera2D camera;
public Screen Screen
{
get
{
return currentScreen;
}
set
{
previousScreen = currentScreen;
currentScreen = value;
if (!Screen.Initiated)
{
Screen.Initiate(graphics.GraphicsDevice, new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight), camera);
}
if (previousScreen != null && previousScreenRenderTarget == null && previousScreen.UseRenderTargetForExitTransition)
{
previousScreenRenderTarget = new RenderTarget2D(graphics.GraphicsDevice, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
}
graphics.GraphicsDevice.SetRenderTarget(previousScreenRenderTarget);
graphics.GraphicsDevice.Clear(Color.Black);
Debug.WriteLine("Showing " + value.GetType().Name);
Debug.WriteLine("Previous screen is " + previousScreen?.GetType().Name);
Screen.Show();
}
}
private bool resizing;
public RhythmBulletGame()
{
@ -104,8 +76,10 @@ namespace RhythmBullet
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
camera = new Camera2D(graphics.GraphicsDevice);
screenManager = new ScreenManager(graphics, camera);
screenManager.RequireNextScreenEvent += ExitTransitionComplete;
QueueContent();
Screen = new LoadingScreen(Content.Load<Texture2D>("RhythmBullet"), 0.7f);
screenManager.Screen = new LoadingScreen(Content.Load<Texture2D>("RhythmBullet"), 0.7f);
}
/// <summary>
@ -115,7 +89,6 @@ namespace RhythmBullet
protected override void UnloadContent()
{
Assets.UnloadAll();
previousScreenRenderTarget?.Dispose();
}
/// <summary>
@ -134,34 +107,8 @@ namespace RhythmBullet
resizing = false;
PostResize();
}
switch (Screen.State)
{
case ScreenState.EnterTransition:
if (previousScreen != null && previousScreen.UseRenderTargetForExitTransition)
{
previousScreen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, Assets.Done);
}
Screen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, Assets.Done);
break;
case ScreenState.ExitTransition:
if (Screen.UseRenderTargetForExitTransition || Screen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, Assets.Done))
{
if (Screen.NextScreen != null)
{
Debug.WriteLine("Changing to the next given screen.");
Screen = Screen.NextScreen;
}
else
{
Debug.WriteLine("Changing to default screen.");
Screen = previousScreen != null ? previousScreen : new MainScreen(Assets);
}
}
break;
case ScreenState.Normal:
Screen.Update(gameTime);
break;
}
screenManager.Update(gameTime, Assets.Done);
InputUtilities.Update();
camera.Update();
@ -174,20 +121,7 @@ namespace RhythmBullet
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Screen.BackgroundColor);
if (Screen.State == ScreenState.EnterTransition && previousScreen != null && previousScreen.UseRenderTargetForExitTransition)
{
graphics.GraphicsDevice.SetRenderTarget(previousScreenRenderTarget);
GraphicsDevice.Clear(previousScreen.BackgroundColor);
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.TransformMatrix);
previousScreen.Draw(spriteBatch);
spriteBatch.End();
graphics.GraphicsDevice.SetRenderTarget(null);
Screen.UpdatePreviousScreenFrame(previousScreenRenderTarget);
}
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.TransformMatrix);
Screen.Draw(spriteBatch);
spriteBatch.End();
screenManager.Draw(spriteBatch);
base.Draw(gameTime);
}
@ -201,16 +135,13 @@ namespace RhythmBullet
resizing = true;
Assets.UnloadAll();
QueueContent();
Screen.AssetLoadStateChange(true);
Screen = new LoadingScreen(Content.Load<Texture2D>("loading_ring"), 0.3f, true);
previousScreenRenderTarget.Dispose();
previousScreenRenderTarget = null;
screenManager.Resize(Content.Load<Texture2D>("loading_ring"));
}
private void PostResize()
{
graphics.ApplyChanges();
Screen.AssetLoadStateChange(false);
screenManager.PostResize();
}
private void QueueContent()
@ -219,5 +150,10 @@ namespace RhythmBullet
Assets.Queue<Texture2D>("default_cover", false);
Assets.Queue<Texture2D>("backgrounds/mainBG");
}
private void ExitTransitionComplete(Screen Screen)
{
Screen.NextScreen = new MainScreen(Assets);
}
}
}

View File

@ -17,7 +17,7 @@ namespace RhythmBullet.Zer01HD.Utilities.ScreenSystem
public bool UseRenderTargetForExitTransition;
public Color BackgroundColor;
public GraphicsDevice GraphicsDevice { get; private set; }
public Screen NextScreen { get; protected set; }
public Screen NextScreen { get; set; }
public Rectangle ScreenSize { get; protected set; }
public bool Initiated { get; private set; }
public Camera2D Camera { get; private set; }

View File

@ -0,0 +1,133 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RhythmBullet.Zer01HD.Utilities.Camera;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RhythmBullet.Zer01HD.Utilities.ScreenSystem
{
public delegate void RequireNextScreen(Screen screen);
public class ScreenManager : IDisposable
{
public event RequireNextScreen RequireNextScreenEvent;
private GraphicsDeviceManager graphics;
private Screen previousScreen;
private RenderTarget2D previousScreenRenderTarget;
private Screen currentScreen;
private Camera2D camera;
public Screen Screen
{
get
{
return currentScreen;
}
set
{
previousScreen = currentScreen;
currentScreen = value;
if (!Screen.Initiated)
{
Screen.Initiate(graphics.GraphicsDevice, new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight), camera);
}
if (previousScreen != null && previousScreenRenderTarget == null && previousScreen.UseRenderTargetForExitTransition)
{
previousScreenRenderTarget = new RenderTarget2D(graphics.GraphicsDevice, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
}
graphics.GraphicsDevice.SetRenderTarget(previousScreenRenderTarget);
graphics.GraphicsDevice.Clear(Color.Black);
Debug.WriteLine("Showing " + value.GetType().Name);
Debug.WriteLine("Previous screen is " + previousScreen?.GetType().Name);
Screen.Show();
}
}
public ScreenManager(GraphicsDeviceManager graphicsDeviceManager, Camera2D camera)
{
this.graphics = graphicsDeviceManager;
this.camera = camera;
}
public void Update(GameTime gameTime, bool assetsDone)
{
switch (Screen.State)
{
case ScreenState.EnterTransition:
if (previousScreen != null && previousScreen.UseRenderTargetForExitTransition)
{
previousScreen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, assetsDone);
}
Screen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, assetsDone);
break;
case ScreenState.ExitTransition:
if (Screen.UseRenderTargetForExitTransition || Screen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, assetsDone))
{
OnRequireNextScreen(Screen);
if (Screen.NextScreen != null)
{
Debug.WriteLine("Changing to the next given screen.");
Screen = Screen.NextScreen;
}
else if (previousScreen != null)
{
Debug.WriteLine("Changing to previous screen.");
Screen = previousScreen;
} else
{
throw new InvalidOperationException("No next screen provided and no previous screen to return to.");
}
}
break;
case ScreenState.Normal:
Screen.Update(gameTime);
break;
}
}
public void Draw(SpriteBatch spriteBatch)
{
graphics.GraphicsDevice.Clear(Screen.BackgroundColor);
if (Screen.State == ScreenState.EnterTransition && previousScreen != null && previousScreen.UseRenderTargetForExitTransition)
{
graphics.GraphicsDevice.SetRenderTarget(previousScreenRenderTarget);
graphics.GraphicsDevice.Clear(previousScreen.BackgroundColor);
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.TransformMatrix);
previousScreen.Draw(spriteBatch);
spriteBatch.End();
graphics.GraphicsDevice.SetRenderTarget(null);
Screen.UpdatePreviousScreenFrame(previousScreenRenderTarget);
}
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.TransformMatrix);
Screen.Draw(spriteBatch);
spriteBatch.End();
}
public void Resize(Texture2D loadingScreenSymbol)
{
Screen.AssetLoadStateChange(true);
Screen = new LoadingScreen(loadingScreenSymbol, 0.3f, true);
previousScreenRenderTarget.Dispose();
previousScreenRenderTarget = null;
}
public void PostResize()
{
Screen.AssetLoadStateChange(false);
}
public void OnRequireNextScreen(Screen screen)
{
RequireNextScreenEvent?.Invoke(screen);
}
public void Dispose()
{
previousScreenRenderTarget?.Dispose();
}
}
}