using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Ninject;
using V3.Input;
using V3.Widgets;
namespace V3.Screens
{
///
/// The screen for the main menu.
///
// ReSharper disable once ClassNeverInstantiated.Global
public class MainScreen : AbstractScreen, IInitializable
{
private readonly GraphicsDeviceManager mGraphicsDeviceManager;
private readonly IMenu mMenu;
private readonly MenuActions mMenuActions;
private readonly WidgetFactory mWidgetFactory;
private readonly ContentManager mContentManager;
private Button mButtonStart;
private Button mButtonLoad;
private Button mButtonOptions;
private Button mButtonTechDemo;
private Button mButtonExit;
private Button mButtonStatistics;
private Button mButtonAchievements;
private Texture2D mTitleImage;
private Texture2D mBackgroundImage;
private Vector2 mImagePosition;
private Random mRandom;
private Vector2 mImageScrollDirection;
private Rectangle TitleImageBounds => mTitleImage.Bounds;
private Rectangle BackgroundImageBounds => mBackgroundImage.Bounds;
private Rectangle ScreenBounds => mGraphicsDeviceManager.GraphicsDevice.Viewport.Bounds;
///
/// Creates a new main screen.
///
public MainScreen(GraphicsDeviceManager graphicsDeviceManager,
VerticalMenu menu, MenuActions menuActions,
WidgetFactory widgetFactory, ContentManager contentManager) : base(false, false)
{
mGraphicsDeviceManager = graphicsDeviceManager;
mMenu = menu;
mMenuActions = menuActions;
mWidgetFactory = widgetFactory;
mContentManager = contentManager;
}
public void Initialize()
{
mMenuActions.ApplyOptions();
mButtonStart = mWidgetFactory.CreateButton("Neues Spiel");
mButtonLoad = mWidgetFactory.CreateButton("Spiel laden");
mButtonLoad.IsEnabled = mMenuActions.CanLoadGame();
mButtonOptions = mWidgetFactory.CreateButton("Optionen");
mButtonStatistics = mWidgetFactory.CreateButton("Statistiken");
mButtonAchievements = mWidgetFactory.CreateButton("Erfolge");
mButtonTechDemo = mWidgetFactory.CreateButton("Tech-Demo");
mButtonExit = mWidgetFactory.CreateButton("Spiel schließen");
mMenu.Widgets.Add(mButtonStart);
mMenu.Widgets.Add(mButtonLoad);
mMenu.Widgets.Add(mButtonOptions);
mMenu.Widgets.Add(mButtonStatistics);
mMenu.Widgets.Add(mButtonAchievements);
mMenu.Widgets.Add(mButtonTechDemo);
mMenu.Widgets.Add(mButtonExit);
mTitleImage = mContentManager.Load("Menu/Titel");
mBackgroundImage = mContentManager.Load("Menu/mainscreen");
mRandom = new Random();
mImagePosition = RandomPosition();
mImageScrollDirection = RandomScrollDirection();
mButtonStart.BackgroundColor = Color.Red;
mButtonLoad.BackgroundColor = Color.Red;
mButtonOptions.BackgroundColor = Color.Red;
mButtonStatistics.BackgroundColor = Color.Red;
mButtonAchievements.BackgroundColor = Color.Red;
mButtonTechDemo.BackgroundColor = Color.Red;
mButtonExit.BackgroundColor = Color.Red;
}
public override bool HandleKeyEvent(IKeyEvent keyEvent)
{
return true;
}
public override bool HandleMouseEvent(IMouseEvent mouseEvent)
{
mMenu.HandleMouseEvent(mouseEvent);
return true;
}
public override void Update(GameTime gameTime)
{
if (mButtonStart.IsClicked)
mMenuActions.StartNewGame();
else if (mButtonLoad.IsClicked)
mMenuActions.OpenLoadScreen();
else if (mButtonOptions.IsClicked)
mMenuActions.OpenOptionsScreen();
else if (mButtonTechDemo.IsClicked)
mMenuActions.OpenTechDemo();
else if (mButtonStatistics.IsClicked)
mMenuActions.OpenStatisticsScreen();
else if (mButtonAchievements.IsClicked)
mMenuActions.OpenAchievementsScreen();
else if (mButtonExit.IsClicked)
mMenuActions.Exit();
mMenu.Update();
UpdateBackgroundPosition();
}
///
/// Draws this object using the given sprite batch.
///
/// a snapshot of the game time
/// the sprite batch to use for drawing
/// this object
public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(mBackgroundImage, mImagePosition, Color.White);
Point titleSize = new Point(ScreenBounds.Width * 9 / 10, ScreenBounds.Width * TitleImageBounds.Height * 9 / 10 / TitleImageBounds.Width);
Point titlePosition = new Point(ScreenBounds.Width / 2 - titleSize.X / 2, ScreenBounds.Height / 20);
spriteBatch.Draw(mTitleImage,
new Rectangle(titlePosition, titleSize),
Color.White);
spriteBatch.End();
mMenu.Draw(spriteBatch);
}
///
/// Calculate a random section of the background image to show.
/// If the screen is larger than the image, just draw it to the upper left corner.
///
/// A random Vector2 fitting the image to the screen.
private Vector2 RandomPosition()
{
Vector2 position;
try
{
var randomX = mRandom.Next(-BackgroundImageBounds.Width + ScreenBounds.Width, 0);
var randomY = mRandom.Next(-BackgroundImageBounds.Height + ScreenBounds.Height, 0);
position = new Vector2(randomX, randomY);
}
catch (ArgumentOutOfRangeException)
{
position = Vector2.Zero;
}
return position;
}
private Vector2 RandomScrollDirection()
{
var imageScrollDirection = new Vector2((float)mRandom.NextDouble(), (float)mRandom.NextDouble());
imageScrollDirection.Normalize();
switch (mRandom.Next(4))
{
case 0:
return imageScrollDirection;
case 1:
return new Vector2(imageScrollDirection.X, -imageScrollDirection.Y);
case 2:
return new Vector2(-imageScrollDirection.X, imageScrollDirection.Y);
case 3:
return new Vector2(-imageScrollDirection.X, -imageScrollDirection.Y);
default:
return imageScrollDirection;
}
}
private void UpdateBackgroundPosition()
{
if (mImagePosition.X < 0 && mImagePosition.X > -BackgroundImageBounds.Width + ScreenBounds.Width
&& mImagePosition.Y < 0 && mImagePosition.Y > -BackgroundImageBounds.Height + ScreenBounds.Height)
{
mImagePosition += mImageScrollDirection;
}
else
{
mImagePosition = RandomPosition();
mImageScrollDirection = RandomScrollDirection();
}
}
}
}