2019-08-06 16:33:49 +02:00
|
|
|
using Coroutine;
|
|
|
|
using Microsoft.Xna.Framework;
|
2020-05-22 20:32:38 +02:00
|
|
|
using Microsoft.Xna.Framework.Content;
|
2019-08-06 16:33:49 +02:00
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
2019-08-07 22:25:33 +02:00
|
|
|
using MLEM.Input;
|
2019-08-09 23:43:50 +02:00
|
|
|
using MLEM.Ui;
|
2019-08-10 21:37:10 +02:00
|
|
|
using MLEM.Ui.Style;
|
2019-08-06 16:33:49 +02:00
|
|
|
|
|
|
|
namespace MLEM.Startup {
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// MlemGame is an extension of MonoGame's default <see cref="Game"/> class.
|
|
|
|
/// It features the default template setup, as well as an <see cref="InputHandler"/>, a <see cref="UiSystem"/> and some additional callback events.
|
|
|
|
/// It also runs all of the <see cref="CoroutineHandler"/> callbacks which can be used through <see cref="CoroutineEvents"/>.
|
|
|
|
/// </summary>
|
2019-08-06 16:33:49 +02:00
|
|
|
public class MlemGame : Game {
|
|
|
|
|
|
|
|
private static MlemGame instance;
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// The static game instance's input handler
|
|
|
|
/// </summary>
|
2019-08-07 22:25:33 +02:00
|
|
|
public static InputHandler Input => instance.InputHandler;
|
2019-08-06 16:33:49 +02:00
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// This game's graphics device manager, initialized in the constructor
|
|
|
|
/// </summary>
|
2019-08-06 16:33:49 +02:00
|
|
|
public readonly GraphicsDeviceManager GraphicsDeviceManager;
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// This game's sprite batch
|
|
|
|
/// </summary>
|
2019-08-07 22:25:33 +02:00
|
|
|
public SpriteBatch SpriteBatch { get; protected set; }
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// This game's input handler. This can easily be accessed through <see cref="Input"/>.
|
|
|
|
/// </summary>
|
2019-08-07 22:25:33 +02:00
|
|
|
public InputHandler InputHandler { get; protected set; }
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// This game's ui system
|
|
|
|
/// </summary>
|
2019-08-09 23:43:50 +02:00
|
|
|
public UiSystem UiSystem { get; protected set; }
|
2019-08-06 16:33:49 +02:00
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// An event that is invoked in <see cref="LoadContent"/>
|
|
|
|
/// </summary>
|
2021-06-09 00:27:50 +02:00
|
|
|
public event GenericCallback OnLoadContent;
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// An event that is invoked in <see cref="Update"/>
|
|
|
|
/// </summary>
|
2021-06-09 00:27:50 +02:00
|
|
|
public event TimeCallback OnUpdate;
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// An event that is invoked in <see cref="Draw"/>
|
|
|
|
/// </summary>
|
2021-06-09 00:27:50 +02:00
|
|
|
public event TimeCallback OnDraw;
|
2019-09-05 14:27:18 +02:00
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// Creates a new MlemGame instance with some default settings
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="windowWidth">The default window width</param>
|
|
|
|
/// <param name="windowHeight">The default window height</param>
|
2020-02-05 22:51:47 +01:00
|
|
|
public MlemGame(int windowWidth = 1280, int windowHeight = 720) {
|
2019-08-06 16:33:49 +02:00
|
|
|
instance = this;
|
2020-02-05 22:51:47 +01:00
|
|
|
|
2019-08-06 16:33:49 +02:00
|
|
|
this.GraphicsDeviceManager = new GraphicsDeviceManager(this) {
|
|
|
|
PreferredBackBufferWidth = windowWidth,
|
|
|
|
PreferredBackBufferHeight = windowHeight,
|
2020-02-05 22:51:47 +01:00
|
|
|
HardwareModeSwitch = false
|
2019-08-06 16:33:49 +02:00
|
|
|
};
|
2020-02-05 22:51:47 +01:00
|
|
|
this.Window.AllowUserResizing = true;
|
|
|
|
this.Content.RootDirectory = "Content";
|
2019-08-06 16:33:49 +02:00
|
|
|
}
|
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <inheritdoc />
|
2019-08-06 16:33:49 +02:00
|
|
|
protected override void LoadContent() {
|
|
|
|
this.SpriteBatch = new SpriteBatch(this.GraphicsDevice);
|
2021-02-18 18:36:29 +01:00
|
|
|
this.InputHandler = new InputHandler(this);
|
2019-12-05 17:52:25 +01:00
|
|
|
this.Components.Add(this.InputHandler);
|
2021-03-29 02:26:44 +02:00
|
|
|
this.UiSystem = new UiSystem(this, new UntexturedStyle(this.SpriteBatch), this.InputHandler);
|
2019-12-05 17:52:25 +01:00
|
|
|
this.Components.Add(this.UiSystem);
|
2019-09-05 14:27:18 +02:00
|
|
|
this.OnLoadContent?.Invoke(this);
|
2019-08-06 16:33:49 +02:00
|
|
|
}
|
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <inheritdoc />
|
2019-12-05 17:35:24 +01:00
|
|
|
protected sealed override void Update(GameTime gameTime) {
|
|
|
|
this.DoUpdate(gameTime);
|
2019-09-05 14:27:18 +02:00
|
|
|
this.OnUpdate?.Invoke(this, gameTime);
|
2020-01-30 00:55:02 +01:00
|
|
|
CoroutineHandler.Tick(gameTime.ElapsedGameTime.TotalSeconds);
|
2019-08-07 22:25:33 +02:00
|
|
|
CoroutineHandler.RaiseEvent(CoroutineEvents.Update);
|
|
|
|
}
|
2019-08-06 16:33:49 +02:00
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <inheritdoc />
|
2019-12-01 20:25:25 +01:00
|
|
|
protected sealed override void Draw(GameTime gameTime) {
|
2019-08-15 14:59:15 +02:00
|
|
|
this.UiSystem.DrawEarly(gameTime, this.SpriteBatch);
|
|
|
|
this.DoDraw(gameTime);
|
2019-08-09 23:43:50 +02:00
|
|
|
this.UiSystem.Draw(gameTime, this.SpriteBatch);
|
2019-09-05 14:27:18 +02:00
|
|
|
this.OnDraw?.Invoke(this, gameTime);
|
2019-08-07 22:25:33 +02:00
|
|
|
CoroutineHandler.RaiseEvent(CoroutineEvents.Draw);
|
2019-08-06 16:33:49 +02:00
|
|
|
}
|
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// This method is called in <see cref="Draw"/>.
|
|
|
|
/// It is the version that should be overridden by implementors to draw game content.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="gameTime">The game's time</param>
|
2019-08-15 14:59:15 +02:00
|
|
|
protected virtual void DoDraw(GameTime gameTime) {
|
|
|
|
base.Draw(gameTime);
|
|
|
|
}
|
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// This method is called in <see cref="Update"/>.
|
|
|
|
/// It is the version that should be overridden by implementors to update game content.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="gameTime">The game's time</param>
|
2019-12-05 17:35:24 +01:00
|
|
|
protected virtual void DoUpdate(GameTime gameTime) {
|
|
|
|
base.Update(gameTime);
|
|
|
|
}
|
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// Static helper method for <see cref="ContentManager.Load{T}"/>.
|
|
|
|
/// This just invokes the game instance's load method.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="name">The name of the content file to load</param>
|
|
|
|
/// <typeparam name="T">The type of content to load</typeparam>
|
|
|
|
/// <returns>The loaded content</returns>
|
2019-08-06 16:33:49 +02:00
|
|
|
public static T LoadContent<T>(string name) {
|
|
|
|
return instance.Content.Load<T>(name);
|
|
|
|
}
|
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// A delegate method used by <see cref="MlemGame.OnLoadContent"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="game">The game in question</param>
|
2019-09-05 14:27:18 +02:00
|
|
|
public delegate void GenericCallback(MlemGame game);
|
|
|
|
|
2020-05-22 20:32:38 +02:00
|
|
|
/// <summary>
|
|
|
|
/// A delegate method used by <see cref="MlemGame.OnUpdate"/> and <see cref="MlemGame.OnDraw"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="game">The game in question</param>
|
|
|
|
/// <param name="time">The game's current time</param>
|
2019-09-05 14:27:18 +02:00
|
|
|
public delegate void TimeCallback(MlemGame game, GameTime time);
|
|
|
|
|
2019-08-06 16:33:49 +02:00
|
|
|
}
|
|
|
|
}
|