using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;
using V3.Input;
namespace V3.Screens
{
///
/// Default implementation of IScreenManager.
///
// ReSharper disable once ClassNeverInstantiated.Global
internal sealed class ScreenManager : IScreenManager
{
private readonly IInputManager mInputManager;
private readonly DebugScreen mDebugScreen;
private readonly ContentManager mContentManager;
private readonly Stack mScreens = new Stack();
///
/// Creates a new screen manager using the given input manager.
///
public ScreenManager(IInputManager inputManager, DebugScreen debugScreen, ContentManager contentManager)
{
mInputManager = inputManager;
mDebugScreen = debugScreen;
mContentManager = contentManager;
}
///
/// Adds a screen to the foreground.
///
/// the screen to add in the foreground
public void AddScreen(IScreen screen)
{
mScreens.Push(screen);
#if NO_AUDIO
#else
if (screen is MainScreen)
{
MediaPlayer.IsRepeating = true;
MediaPlayer.Play(mContentManager.Load("Sounds/Kosta_T_-_06"));
}
else if (screen is GameScreen)
{
MediaPlayer.IsRepeating = true;
MediaPlayer.Play(mContentManager.Load("Sounds/Afraid_to_Go"));
}
//else if (screen is PauseScreen)
//{
// mAbstractCreature.GetSelf();
// mAbstractCreature.mSoundEffectInstance.Stop();
// mAbstractCreature.mSoundEffectInstanceFight.Stop();
// mAbstractCreature.mSoundEffectInstanceHorse.Stop();
// mAbstractCreature.mSoundEffectInstanceKnight.Stop();
// mAbstractCreature.mSoundEffectInstanceMeatball.Stop();
//}
#endif
}
///
/// Removes the given screen if it is on the top of the screen stack.
///
/// the screen to remove
public void RemoveScreen(IScreen screen)
{
if (mScreens.Count > 0 && screen.Equals(mScreens.Peek()))
{
mScreens.Pop();
}
}
///
/// Clears the screen stack.
///
public void Clear()
{
mScreens.Clear();
}
///
/// Draws the top screen and, if enabled, the lower screens. The draw
/// order is from bottom to top, i. e. the lowest enabled screen is
/// drawn first, and the top screen is drawn last.
///
/// a snapshot of the game time
/// the sprite batch to use for drawing
///
public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
var drawScreens = new Stack();
foreach (var screen in mScreens)
{
drawScreens.Push(screen);
if (!screen.DrawLower)
break;
}
foreach (var screen in drawScreens)
{
screen.Draw(gameTime, spriteBatch);
}
mDebugScreen.Draw(gameTime, spriteBatch);
}
///
/// Updates the top screen and, if enabled, the lower screens. The
/// update order is from top to bottom, i. e. the lowest enabled screen
/// is drawn first, and the top screen is drawn last.
///
/// a snapshot of the game time
public void Update(GameTime gameTime)
{
mInputManager.Update();
HandleInputEvents();
mDebugScreen.Update(gameTime);
var currentScreens = new Stack(new Stack(mScreens));
foreach (var screen in currentScreens)
{
screen.Update(gameTime);
if (!screen.UpdateLower)
break;
}
}
private void HandleInputEvents()
{
// We need to clone the stack as the input management methods
// might want to modify the screen stack. We need two stacks as
// each stack reverses the order.
var currentScreens = new Stack(new Stack(mScreens));
foreach (var keyEvent in mInputManager.KeyEvents)
{
foreach (var screen in currentScreens)
{
if (screen.HandleKeyEvent(keyEvent))
break;
}
}
foreach (var mouseEvent in mInputManager.MouseEvents)
{
foreach (var screen in currentScreens)
{
if (screen.HandleMouseEvent(mouseEvent))
break;
}
}
}
public GameScreen GetGameScreen()
{
foreach (var screen in mScreens)
{
if (screen is GameScreen)
return (GameScreen) screen;
}
return null;
}
}
}