using Coroutine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Input;
using MLEM.Ui;
using MLEM.Ui.Style;
namespace MLEM.Startup {
///
/// MlemGame is an extension of MonoGame's default class.
/// It features the default template setup, as well as an , a and some additional callback events.
/// It also runs all of the callbacks which can be used through .
///
public class MlemGame : Game {
private static MlemGame instance;
///
/// The static game instance's input handler
///
public static InputHandler Input => MlemGame.instance.InputHandler;
///
/// This game's graphics device manager, initialized in the constructor
///
public readonly GraphicsDeviceManager GraphicsDeviceManager;
///
/// This game's sprite batch
///
public SpriteBatch SpriteBatch { get; protected set; }
///
/// This game's input handler. This can easily be accessed through .
///
public InputHandler InputHandler { get; protected set; }
///
/// This game's ui system
///
public UiSystem UiSystem { get; protected set; }
///
/// An event that is invoked in .
///
public event GenericCallback OnLoadContent;
///
/// An event that is invoked in , before is called.
///
public event TimeCallback PreUpdate;
///
/// An event that is invoked in , after is called.
///
public event TimeCallback OnUpdate;
///
/// An event that is invoked in , before is called.
///
public event TimeCallback PreDraw;
///
/// An event that is invoked in , after is called.
///
public event TimeCallback OnDraw;
///
/// Creates a new MlemGame instance with some default settings
///
/// The default window width
/// The default window height
public MlemGame(int windowWidth = 1280, int windowHeight = 720) {
MlemGame.instance = this;
this.GraphicsDeviceManager = new GraphicsDeviceManager(this) {
PreferredBackBufferWidth = windowWidth,
PreferredBackBufferHeight = windowHeight,
HardwareModeSwitch = false
};
this.Window.AllowUserResizing = true;
this.Content.RootDirectory = "Content";
}
///
/// Override this to load graphical resources required by the game.
///
protected override void LoadContent() {
this.SpriteBatch = new SpriteBatch(this.GraphicsDevice);
this.InputHandler = new InputHandler(this);
this.Components.Add(this.InputHandler);
this.UiSystem = new UiSystem(this, this.InitializeDefaultUiStyle(this.SpriteBatch), this.InputHandler);
this.Components.Add(this.UiSystem);
this.OnLoadContent?.Invoke(this);
}
///
/// Called when the game should update.
/// Updates the instances attached to this game.
/// Override to update your game.
///
/// The elapsed time since the last call to .
protected sealed override void Update(GameTime gameTime) {
this.PreUpdate?.Invoke(this, gameTime);
CoroutineHandler.RaiseEvent(CoroutineEvents.PreUpdate);
this.DoUpdate(gameTime);
this.OnUpdate?.Invoke(this, gameTime);
CoroutineHandler.Tick(gameTime.ElapsedGameTime.TotalSeconds);
CoroutineHandler.RaiseEvent(CoroutineEvents.Update);
}
///
/// Called when the game should draw a frame.
/// Draws the instances attached to this game.
/// Override to render your game.
///
/// A instance containing the elapsed time since the last call to and the total time elapsed since the game started.
protected sealed override void Draw(GameTime gameTime) {
this.PreDraw?.Invoke(this, gameTime);
CoroutineHandler.RaiseEvent(CoroutineEvents.PreDraw);
#pragma warning disable CS0618
this.UiSystem.DrawEarly(gameTime, this.SpriteBatch);
#pragma warning restore CS0618
this.DoDraw(gameTime);
this.UiSystem.Draw(gameTime, this.SpriteBatch);
this.OnDraw?.Invoke(this, gameTime);
CoroutineHandler.RaiseEvent(CoroutineEvents.Draw);
}
///
/// This method is called in .
/// It is the version that should be overridden by implementors to draw game content.
///
/// The game's time
protected virtual void DoDraw(GameTime gameTime) {
base.Draw(gameTime);
}
///
/// This method is called in .
/// It is the version that should be overridden by implementors to update game content.
///
/// The game's time
protected virtual void DoUpdate(GameTime gameTime) {
base.Update(gameTime);
}
///
/// This method is called in when the is initialized.
/// Override this method to easily modify or create a new default for this game's .
///
/// The sprite batch to use
/// The to use for this game's .
protected virtual UiStyle InitializeDefaultUiStyle(SpriteBatch batch) {
return new UntexturedStyle(batch);
}
///
/// Static helper method for .
/// This just invokes the game instance's load method.
///
/// The name of the content file to load
/// The type of content to load
/// The loaded content
public static T LoadContent(string name) {
return MlemGame.instance.Content.Load(name);
}
///
/// A delegate method used by .
///
/// The game in question
public delegate void GenericCallback(MlemGame game);
///
/// A delegate method used by and .
///
/// The game in question
/// The game's current time
public delegate void TimeCallback(MlemGame game, GameTime time);
}
}