mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 20:58:34 +01:00
start on xml documentation, yay
This commit is contained in:
parent
b836b486a2
commit
d8daa3779a
12 changed files with 439 additions and 9 deletions
|
@ -5,10 +5,21 @@ using MLEM.Misc;
|
|||
using MLEM.Textures;
|
||||
|
||||
namespace MLEM.Animations {
|
||||
/// <summary>
|
||||
/// A sprite animation that allows for any number of frames that each last any number of seconds
|
||||
/// </summary>
|
||||
public class SpriteAnimation : GenericDataHolder {
|
||||
|
||||
private AnimationFrame[] frames;
|
||||
/// <summary>
|
||||
/// Returns the <see cref="AnimationFrame"/> at the given index.
|
||||
/// Index ordering is based on the order that animation frames were added in.
|
||||
/// </summary>
|
||||
/// <param name="index">The index in the list of animation frames</param>
|
||||
public AnimationFrame this[int index] => this.frames[index];
|
||||
/// <summary>
|
||||
/// The frame that the animation is currently on.
|
||||
/// </summary>
|
||||
public AnimationFrame CurrentFrame {
|
||||
get {
|
||||
// we might have overshot the end time by a little bit, so just return the last frame
|
||||
|
@ -24,35 +35,86 @@ namespace MLEM.Animations {
|
|||
return this.frames[0];
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The texture region that the animation's <see cref="CurrentFrame"/> has
|
||||
/// </summary>
|
||||
public TextureRegion CurrentRegion => this.CurrentFrame.Region;
|
||||
/// <summary>
|
||||
/// The total amount of time that this animation has.
|
||||
/// This is auatomatically calculated based on the frame time of each frame.
|
||||
/// </summary>
|
||||
public readonly double TotalTime;
|
||||
/// <summary>
|
||||
/// The amount of seconds that the animation has been going on for.
|
||||
/// If <see cref="TotalTime"/> is reached, this value resets to 0.
|
||||
/// </summary>
|
||||
public double TimeIntoAnimation { get; private set; }
|
||||
/// <summary>
|
||||
/// The finished state of this animation.
|
||||
/// This is only true for longer than a frame if <see cref="IsLooping"/> is false.
|
||||
/// </summary>
|
||||
public bool IsFinished { get; private set; }
|
||||
/// <summary>
|
||||
/// The name of this animation. This is useful if used in combination with <see cref="SpriteAnimationGroup"/>.
|
||||
/// </summary>
|
||||
public string Name;
|
||||
/// <summary>
|
||||
/// The speed multiplier that this animation should run with.
|
||||
/// Numbers higher than 1 will increase the speed.
|
||||
/// </summary>
|
||||
public float SpeedMultiplier = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Set to false to stop this animation from looping.
|
||||
/// To check if the animation has finished playing, see <see cref="IsFinished"/>.
|
||||
/// </summary>
|
||||
public bool IsLooping = true;
|
||||
public Completed OnCompleted;
|
||||
/// <summary>
|
||||
/// A callback that gets fired when the animation completes.
|
||||
/// </summary>
|
||||
public event Completed OnCompleted;
|
||||
/// <summary>
|
||||
/// Set this to true to pause the playback of the animation.
|
||||
/// <see cref="TimeIntoAnimation"/> will not continue and the <see cref="CurrentFrame"/> will not change.
|
||||
/// </summary>
|
||||
public bool IsPaused;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new sprite animation that contains the given frames.
|
||||
/// </summary>
|
||||
/// <param name="frames">The frames this animation should have</param>
|
||||
public SpriteAnimation(params AnimationFrame[] frames) {
|
||||
this.frames = frames;
|
||||
foreach (var frame in frames)
|
||||
this.TotalTime += frame.Seconds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new sprite animation that contains the given texture regions as frames.
|
||||
/// </summary>
|
||||
/// <param name="timePerFrame">The amount of time that each frame should last for</param>
|
||||
/// <param name="regions">The texture regions that should make up this animation</param>
|
||||
public SpriteAnimation(double timePerFrame, params TextureRegion[] regions)
|
||||
: this(Array.ConvertAll(regions, region => new AnimationFrame(region, timePerFrame))) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new sprite animation based on the given texture regions in rectangle-based format.
|
||||
/// </summary>
|
||||
/// <param name="timePerFrame">The amount of time that each frame should last for</param>
|
||||
/// <param name="texture">The texture that the regions should come from</param>
|
||||
/// <param name="regions">The texture regions that should make up this animation</param>
|
||||
public SpriteAnimation(double timePerFrame, Texture2D texture, params Rectangle[] regions)
|
||||
: this(timePerFrame, Array.ConvertAll(regions, region => new TextureRegion(texture, region))) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates this animation, causing <see cref="TimeIntoAnimation"/> to be increased and the <see cref="CurrentFrame"/> to be updated.
|
||||
/// </summary>
|
||||
/// <param name="time">The game's time</param>
|
||||
public void Update(GameTime time) {
|
||||
this.SetTime(this.TimeIntoAnimation + time.ElapsedGameTime.TotalSeconds * this.SpeedMultiplier);
|
||||
}
|
||||
|
||||
|
||||
internal void SetTime(double totalTime) {
|
||||
if (this.IsFinished || this.IsPaused)
|
||||
return;
|
||||
|
@ -67,6 +129,9 @@ namespace MLEM.Animations {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restarts this animation from the first frame.
|
||||
/// </summary>
|
||||
public void Restart() {
|
||||
this.TimeIntoAnimation = 0;
|
||||
this.IsFinished = false;
|
||||
|
@ -77,11 +142,25 @@ namespace MLEM.Animations {
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a single frame of a <see cref="SpriteAnimation"/>
|
||||
/// </summary>
|
||||
public class AnimationFrame {
|
||||
|
||||
/// <summary>
|
||||
/// The texture region that this frame should render
|
||||
/// </summary>
|
||||
public readonly TextureRegion Region;
|
||||
/// <summary>
|
||||
/// The total amount of seconds that this frame should last for
|
||||
/// </summary>
|
||||
public readonly double Seconds;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new animation frame based on a texture region and a time
|
||||
/// </summary>
|
||||
/// <param name="region">The texture region that this frame should render</param>
|
||||
/// <param name="seconds">The total amount of seconds that this frame should last for</param>
|
||||
public AnimationFrame(TextureRegion region, double seconds) {
|
||||
this.Region = region;
|
||||
this.Seconds = seconds;
|
||||
|
|
|
@ -5,7 +5,11 @@ using MLEM.Misc;
|
|||
using MLEM.Textures;
|
||||
|
||||
namespace MLEM.Animations {
|
||||
public class SpriteAnimationGroup : GenericDataHolder{
|
||||
/// <summary>
|
||||
/// Represents a list of <see cref="SpriteAnimation"/> objects with a condition and priority attached to them.
|
||||
/// Sprite animation groups can be used if any single entity should have multiple animations (like up, down, left, right standing and running animations) that should be automatically managed.
|
||||
/// </summary>
|
||||
public class SpriteAnimationGroup : GenericDataHolder {
|
||||
|
||||
private readonly List<ConditionedAnimation> animations = new List<ConditionedAnimation>();
|
||||
private ConditionedAnimation currAnimation;
|
||||
|
@ -20,11 +24,24 @@ namespace MLEM.Animations {
|
|||
}
|
||||
set => this.currAnimation = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// The animation that is currently playing
|
||||
/// </summary>
|
||||
public SpriteAnimation CurrentAnimation => this.CurrAnimation?.Animation;
|
||||
/// <summary>
|
||||
/// The frame that <see cref="CurrentAnimation"/> is displaying
|
||||
/// </summary>
|
||||
public AnimationFrame CurrentFrame => this.CurrentAnimation?.CurrentFrame;
|
||||
/// <summary>
|
||||
/// The region that <see cref="CurrentFrame"/> has
|
||||
/// </summary>
|
||||
public TextureRegion CurrentRegion => this.CurrentAnimation?.CurrentRegion;
|
||||
public AnimationChanged OnAnimationChanged;
|
||||
/// <summary>
|
||||
/// A callback for when the currently displaying animation has changed due to a condition with a higher priority being met.
|
||||
/// </summary>
|
||||
public event AnimationChanged OnAnimationChanged;
|
||||
private bool isDirty;
|
||||
/// <inheritdoc cref="SpriteAnimation.SpeedMultiplier"/>
|
||||
public float SpeedMultiplier {
|
||||
set {
|
||||
foreach (var anim in this.animations)
|
||||
|
@ -32,23 +49,36 @@ namespace MLEM.Animations {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="SpriteAnimation"/> to this group.
|
||||
/// </summary>
|
||||
/// <param name="anim">The animation to add</param>
|
||||
/// <param name="condition">The condition that needs to be met for this animation to play</param>
|
||||
/// <param name="priority">The priority of this animation. The higher the priority, the earlier it is picked for playing.</param>
|
||||
/// <returns>This group, for chaining</returns>
|
||||
public SpriteAnimationGroup Add(SpriteAnimation anim, Func<bool> condition, int priority = 0) {
|
||||
this.animations.Add(new ConditionedAnimation(anim, condition, priority));
|
||||
this.isDirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteAnimation.Update"/>
|
||||
public void Update(GameTime time) {
|
||||
this.FindAnimationToPlay();
|
||||
if (this.CurrAnimation != null)
|
||||
this.CurrAnimation.Animation.Update(time);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find an animation in this group by name and returns it.
|
||||
/// </summary>
|
||||
/// <param name="name">The <see cref="SpriteAnimation.Name"/> of the animation</param>
|
||||
/// <returns>The animation by that name, or <c>null</c> if there is none</returns>
|
||||
public SpriteAnimation ByName(string name) {
|
||||
return this.animations.Find(anim => anim.Animation.Name == name)?.Animation;
|
||||
}
|
||||
|
||||
public void FindAnimationToPlay() {
|
||||
private void FindAnimationToPlay() {
|
||||
ConditionedAnimation animToPlay = null;
|
||||
if (this.CurrAnimation != null && this.CurrAnimation.ShouldPlay())
|
||||
animToPlay = this.CurrAnimation;
|
||||
|
|
|
@ -5,18 +5,45 @@ using MLEM.Extensions;
|
|||
using MLEM.Misc;
|
||||
|
||||
namespace MLEM.Cameras {
|
||||
/// <summary>
|
||||
/// Represents a simple, orthographic 2-dimensional camera that can be moved, scaled and that supports automatic viewport sizing.
|
||||
/// To draw with the camera's positioning and scaling applied, use <see cref="ViewMatrix"/>.
|
||||
/// </summary>
|
||||
public class Camera {
|
||||
|
||||
/// <summary>
|
||||
/// The top-left corner of the camera's viewport.
|
||||
/// <seealso cref="LookingPosition"/>
|
||||
/// </summary>
|
||||
public Vector2 Position;
|
||||
/// <summary>
|
||||
/// The scale that this camera's <see cref="ViewMatrix"/> should have.
|
||||
/// </summary>
|
||||
public float Scale {
|
||||
get => this.scale;
|
||||
set => this.scale = MathHelper.Clamp(value, this.MinScale, this.MaxScale);
|
||||
}
|
||||
private float scale = 1;
|
||||
/// <summary>
|
||||
/// The minimum <see cref="Scale"/> that the camera can have
|
||||
/// </summary>
|
||||
public float MinScale = 0;
|
||||
/// <summary>
|
||||
/// The maximum <see cref="Scale"/> that the camera can have
|
||||
/// </summary>
|
||||
public float MaxScale = float.MaxValue;
|
||||
/// <summary>
|
||||
/// If this is true, the camera will automatically adapt to changed screen sizes.
|
||||
/// You can use <see cref="AutoScaleReferenceSize"/> to determine the initial screen size that this camera should base its calculations on.
|
||||
/// </summary>
|
||||
public bool AutoScaleWithScreen;
|
||||
/// <summary>
|
||||
/// <seealso cref="AutoScaleWithScreen"/>
|
||||
/// </summary>
|
||||
public Point AutoScaleReferenceSize;
|
||||
/// <summary>
|
||||
/// The scale that this camera currently has, based on <see cref="Scale"/> and <see cref="AutoScaleReferenceSize"/> if <see cref="AutoScaleWithScreen"/> is true.
|
||||
/// </summary>
|
||||
public float ActualScale {
|
||||
get {
|
||||
if (!this.AutoScaleWithScreen)
|
||||
|
@ -24,6 +51,10 @@ namespace MLEM.Cameras {
|
|||
return Math.Min(this.Viewport.Width / (float) this.AutoScaleReferenceSize.X, this.Viewport.Height / (float) this.AutoScaleReferenceSize.Y) * this.Scale;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The matrix that this camera "sees", based on its position and scale.
|
||||
/// Use this in your <see cref="SpriteBatch.Begin"/> calls to render based on the camera's viewport.
|
||||
/// </summary>
|
||||
public Matrix ViewMatrix {
|
||||
get {
|
||||
var sc = this.ActualScale;
|
||||
|
@ -33,39 +64,73 @@ namespace MLEM.Cameras {
|
|||
return Matrix.CreateScale(sc, sc, 1) * Matrix.CreateTranslation(new Vector3(pos, 0));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The bottom-right corner of the camera's viewport
|
||||
/// <seealso cref="LookingPosition"/>
|
||||
/// </summary>
|
||||
public Vector2 Max {
|
||||
get => this.Position + this.ScaledViewport;
|
||||
set => this.Position = value - this.ScaledViewport;
|
||||
}
|
||||
/// <summary>
|
||||
/// The center of the camera's viewport, or the position that the camera is looking at.
|
||||
/// </summary>
|
||||
public Vector2 LookingPosition {
|
||||
get => this.Position + this.ScaledViewport / 2;
|
||||
set => this.Position = value - this.ScaledViewport / 2;
|
||||
}
|
||||
public Rectangle Viewport => this.graphicsDevice.Viewport.Bounds;
|
||||
public Vector2 ScaledViewport => new Vector2(this.Viewport.Width, this.Viewport.Height) / this.ActualScale;
|
||||
private Rectangle Viewport => this.graphicsDevice.Viewport.Bounds;
|
||||
private Vector2 ScaledViewport => new Vector2(this.Viewport.Width, this.Viewport.Height) / this.ActualScale;
|
||||
|
||||
private readonly bool roundPosition;
|
||||
private readonly GraphicsDevice graphicsDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new camera.
|
||||
/// </summary>
|
||||
/// <param name="graphicsDevice">The game's graphics device</param>
|
||||
/// <param name="roundPosition">If this is true, the camera's <see cref="Position"/> and related properties will be rounded to full integers.</param>
|
||||
public Camera(GraphicsDevice graphicsDevice, bool roundPosition = true) {
|
||||
this.graphicsDevice = graphicsDevice;
|
||||
this.AutoScaleReferenceSize = this.Viewport.Size;
|
||||
this.roundPosition = roundPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a given position in screen space to world space
|
||||
/// </summary>
|
||||
/// <param name="pos">The position in screen space</param>
|
||||
/// <returns>The position in world space</returns>
|
||||
public Vector2 ToWorldPos(Vector2 pos) {
|
||||
return Vector2.Transform(pos, Matrix.Invert(this.ViewMatrix));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a given position in world space to screen space
|
||||
/// </summary>
|
||||
/// <param name="pos">The position in world space</param>
|
||||
/// <returns>The position in camera space</returns>
|
||||
public Vector2 ToCameraPos(Vector2 pos) {
|
||||
return Vector2.Transform(pos, this.ViewMatrix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the area that this camera can see, in world space.
|
||||
/// This can be useful for culling of tile and other entity renderers.
|
||||
/// </summary>
|
||||
/// <returns>A rectangle that represents the camera's visible area in world space</returns>
|
||||
public RectangleF GetVisibleRectangle() {
|
||||
var start = this.ToWorldPos(Vector2.Zero);
|
||||
return new RectangleF(start, this.ToWorldPos(new Vector2(this.Viewport.Width, this.Viewport.Height)) - start);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces the camera's bounds into the given min and max positions in world space.
|
||||
/// If the space represented by the given values is smaller than what the camera can see, its position will be forced into the center of the area.
|
||||
/// </summary>
|
||||
/// <param name="min">The top left bound, in world space</param>
|
||||
/// <param name="max">The bottom right bound, in world space</param>
|
||||
/// <returns>Whether or not the camera's position changed as a result of the constraint</returns>
|
||||
public bool ConstrainWorldBounds(Vector2 min, Vector2 max) {
|
||||
var lastPos = this.Position;
|
||||
var visible = this.GetVisibleRectangle();
|
||||
|
@ -89,6 +154,11 @@ namespace MLEM.Cameras {
|
|||
return !this.Position.Equals(lastPos, 0.001F);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Zoom in the camera's view by a given amount, optionally focusing on a given center point.
|
||||
/// </summary>
|
||||
/// <param name="delta">The amount to zoom in or out by</param>
|
||||
/// <param name="zoomCenter">The position that should be regarded as the zoom's center, in screen space. The default value is the center.</param>
|
||||
public void Zoom(float delta, Vector2? zoomCenter = null) {
|
||||
var center = (zoomCenter ?? this.Viewport.Size.ToVector2() / 2) / this.ActualScale;
|
||||
var lastScale = this.Scale;
|
||||
|
|
|
@ -8,6 +8,9 @@ using Microsoft.Xna.Framework.Content;
|
|||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace MLEM.Content {
|
||||
/// <summary>
|
||||
/// Represents a version of <see cref="ContentManager"/> that doesn't load content binary <c>xnb</c> files, but rather as their regular formats.
|
||||
/// </summary>
|
||||
public class RawContentManager : ContentManager, IGameComponent {
|
||||
|
||||
private static readonly RawContentReader[] Readers = AppDomain.CurrentDomain.GetAssemblies()
|
||||
|
@ -18,14 +21,29 @@ namespace MLEM.Content {
|
|||
|
||||
private readonly List<IDisposable> disposableAssets = new List<IDisposable>();
|
||||
|
||||
/// <summary>
|
||||
/// The graphics device that this content manager uses
|
||||
/// </summary>
|
||||
public readonly GraphicsDevice GraphicsDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new content manager with an optionally specified root directory.
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider">The service provider of your game</param>
|
||||
/// <param name="rootDirectory">The root directory. Defaults to "Content"</param>
|
||||
public RawContentManager(IServiceProvider serviceProvider, string rootDirectory = "Content") :
|
||||
base(serviceProvider, rootDirectory) {
|
||||
if (serviceProvider.GetService(typeof(IGraphicsDeviceService)) is IGraphicsDeviceService s)
|
||||
this.GraphicsDevice = s.GraphicsDevice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads a raw asset with the given name, based on the <see cref="ContentManager.RootDirectory"/>.
|
||||
/// If the asset was previously loaded using this method, the cached asset is merely returned.
|
||||
/// </summary>
|
||||
/// <param name="assetName">The path and name of the asset to load, without extension.</param>
|
||||
/// <typeparam name="T">The type of asset to load</typeparam>
|
||||
/// <returns>The asset, either loaded from the cache, or from disk.</returns>
|
||||
public override T Load<T>(string assetName) {
|
||||
if (this.LoadedAssets.TryGetValue(assetName, out var ret) && ret is T t)
|
||||
return t;
|
||||
|
|
|
@ -2,26 +2,59 @@ using System;
|
|||
using System.IO;
|
||||
|
||||
namespace MLEM.Content {
|
||||
/// <summary>
|
||||
/// Represents a way for any kind of raw content file to be read using a <see cref="RawContentManager"/>
|
||||
/// </summary>
|
||||
public abstract class RawContentReader {
|
||||
|
||||
/// <summary>
|
||||
/// Returns if the given type can be loaded by this content reader
|
||||
/// </summary>
|
||||
/// <param name="t">The type of asset</param>
|
||||
/// <returns>If <see cref="t"/> can be loaded by this content reader</returns>
|
||||
public abstract bool CanRead(Type t);
|
||||
|
||||
/// <summary>
|
||||
/// Reads the content file from disk and returns it.
|
||||
/// </summary>
|
||||
/// <param name="manager">The <see cref="RawContentManager"/> that is loading the asset</param>
|
||||
/// <param name="assetPath">The full path to the asset, starting from the <see cref="RawContentManager.RootDirectory"/></param>
|
||||
/// <param name="stream">A stream that leads to this asset</param>
|
||||
/// <param name="t">The type of asset to load</param>
|
||||
/// <param name="existing">If this asset is being reloaded, this value contains the previous version of the asset.</param>
|
||||
/// <returns>The loaded asset</returns>
|
||||
public abstract object Read(RawContentManager manager, string assetPath, Stream stream, Type t, object existing);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the list of file extensions that this reader can read from.
|
||||
/// </summary>
|
||||
/// <returns>The list of valid extensions</returns>
|
||||
public abstract string[] GetFileExtensions();
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract class RawContentReader<T> : RawContentReader {
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanRead(Type t) {
|
||||
return typeof(T).IsAssignableFrom(t);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override object Read(RawContentManager manager, string assetPath, Stream stream, Type t, object existing) {
|
||||
return this.Read(manager, assetPath, stream, (T) existing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the content file that is represented by our generic type from disk.
|
||||
/// </summary>
|
||||
/// <param name="manager">The <see cref="RawContentManager"/> that is loading the asset</param>
|
||||
/// <param name="assetPath">The full path to the asset, starting from the <see cref="RawContentManager.RootDirectory"/></param>
|
||||
/// <param name="stream">A stream that leads to this asset</param>
|
||||
/// <param name="t">The type of asset to load</param>
|
||||
/// <param name="existing">If this asset is being reloaded, this value contains the previous version of the asset.</param>
|
||||
/// <returns>The loaded asset</returns>
|
||||
protected abstract T Read(RawContentManager manager, string assetPath, Stream stream, T existing);
|
||||
|
||||
}
|
||||
|
|
|
@ -5,20 +5,43 @@ using Microsoft.Xna.Framework;
|
|||
namespace MLEM.Extensions {
|
||||
public static class ColorExtensions {
|
||||
|
||||
/// <summary>
|
||||
/// Returns an inverted version of the color.
|
||||
/// </summary>
|
||||
/// <param name="color">The color to invert</param>
|
||||
/// <returns>The inverted color</returns>
|
||||
public static Color Invert(this Color color) {
|
||||
return new Color(Math.Abs(255 - color.R), Math.Abs(255 - color.G), Math.Abs(255 - color.B), color.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a hexadecimal number into a color.
|
||||
/// The number should be in the format <c>0xaarrggbb</c>.
|
||||
/// </summary>
|
||||
/// <param name="value">The number to parse</param>
|
||||
/// <returns>The resulting color</returns>
|
||||
public static Color FromHex(uint value) {
|
||||
return new Color((int) (value >> 16 & 0xFF), (int) (value >> 8 & 0xFF), (int) (value >> 0 & 0xFF), (int) (value >> 24 & 0xFF));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a hexadecimal string into a color.
|
||||
/// The string can optionally start with a <c>#</c>.
|
||||
/// </summary>
|
||||
/// <param name="value">The string to parse</param>
|
||||
/// <returns>The resulting color</returns>
|
||||
public static Color FromHex(string value) {
|
||||
if (value.StartsWith("#"))
|
||||
value = value.Substring(1);
|
||||
return FromHex(uint.Parse(value, NumberStyles.HexNumber));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the alpha value from <see cref="other"/> into this color.
|
||||
/// </summary>
|
||||
/// <param name="color">The color</param>
|
||||
/// <param name="other">The color to copy the alpha from</param>
|
||||
/// <returns>The <see cref="color"/> with <see cref="other"/>'s alpha value</returns>
|
||||
public static Color CopyAlpha(this Color color, Color other) {
|
||||
return color * (other.A / 255F);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,12 @@ namespace MLEM.Extensions {
|
|||
private static int lastWidth;
|
||||
private static int lastHeight;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the graphics device manager to fullscreen, properly taking into account the preferred backbuffer width and height to avoid lower resolutions for higher resolution screens.
|
||||
/// </summary>
|
||||
/// <param name="manager">The graphics device manager</param>
|
||||
/// <param name="fullscreen">True if fullscreen should be enabled, false if disabled</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown when changing out of fullscreen mode before changing into fullscreen mode using this method</exception>
|
||||
public static void SetFullscreen(this GraphicsDeviceManager manager, bool fullscreen) {
|
||||
manager.IsFullScreen = fullscreen;
|
||||
if (fullscreen) {
|
||||
|
@ -29,6 +35,10 @@ namespace MLEM.Extensions {
|
|||
manager.ApplyChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save version of <see cref="GraphicsDeviceManager.ApplyChanges"/> that doesn't reset window size to defaults
|
||||
/// </summary>
|
||||
/// <param name="manager">The graphics device manager</param>
|
||||
public static void ApplyChangesSafely(this GraphicsDeviceManager manager) {
|
||||
// If we don't do this, then applying changes will cause the
|
||||
// graphics device manager to reset the window size to the
|
||||
|
@ -39,6 +49,11 @@ namespace MLEM.Extensions {
|
|||
manager.ApplyChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets preferred width and height back to the window's default bound values.
|
||||
/// </summary>
|
||||
/// <param name="manager">The graphics device manager</param>
|
||||
/// <param name="window">The window whose bounds to use</param>
|
||||
public static void ResetWidthAndHeight(this GraphicsDeviceManager manager, GameWindow window) {
|
||||
var (_, _, width, height) = window.ClientBounds;
|
||||
manager.PreferredBackBufferWidth = Math.Max(height, width);
|
||||
|
@ -46,6 +61,13 @@ namespace MLEM.Extensions {
|
|||
manager.ApplyChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a new <see cref="TargetContext"/> using the specified render target.
|
||||
/// The returned context automatically disposes when used in a <c>using</c> statement, which causes any previously applied render targets to be reapplied automatically.
|
||||
/// </summary>
|
||||
/// <param name="device">The graphics device</param>
|
||||
/// <param name="target">The render target to apply</param>
|
||||
/// <returns></returns>
|
||||
public static TargetContext WithRenderTarget(this GraphicsDevice device, RenderTarget2D target) {
|
||||
return new TargetContext(device, target);
|
||||
}
|
||||
|
|
|
@ -5,68 +5,115 @@ using MLEM.Misc;
|
|||
namespace MLEM.Extensions {
|
||||
public static class NumberExtensions {
|
||||
|
||||
/// <inheritdoc cref="Math.Floor(decimal)"/>
|
||||
public static int Floor(this float f) {
|
||||
return (int) Math.Floor(f);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Math.Ceiling(decimal)"/>
|
||||
public static int Ceil(this float f) {
|
||||
return (int) Math.Ceiling(f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for decimal equality with a given tolerance.
|
||||
/// </summary>
|
||||
/// <param name="first">The first number to equate</param>
|
||||
/// <param name="second">The second number to equate</param>
|
||||
/// <param name="tolerance">The equality tolerance</param>
|
||||
/// <returns>Whether or not <see cref="first"/> and <see cref="second"/> are different by at most <see cref="tolerance"/></returns>
|
||||
public static bool Equals(this float first, float second, float tolerance) {
|
||||
return Math.Abs(first- second) <= tolerance;
|
||||
return Math.Abs(first - second) <= tolerance;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Equals(float,float,float)"/>
|
||||
public static bool Equals(this Vector2 first, Vector2 second, float tolerance) {
|
||||
return Math.Abs(first.X - second.X) <= tolerance && Math.Abs(first.Y - second.Y) <= tolerance;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Equals(float,float,float)"/>
|
||||
public static bool Equals(this Vector3 first, Vector3 second, float tolerance) {
|
||||
return Math.Abs(first.X - second.X) <= tolerance && Math.Abs(first.Y - second.Y) <= tolerance && Math.Abs(first.Z - second.Z) <= tolerance;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Equals(float,float,float)"/>
|
||||
public static bool Equals(this Vector4 first, Vector4 second, float tolerance) {
|
||||
return Math.Abs(first.X - second.X) <= tolerance && Math.Abs(first.Y - second.Y) <= tolerance && Math.Abs(first.Z - second.Z) <= tolerance && Math.Abs(first.W - second.W) <= tolerance;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Math.Floor(decimal)"/>
|
||||
public static Vector2 Floor(this Vector2 vec) {
|
||||
return new Vector2(vec.X.Floor(), vec.Y.Floor());
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Math.Floor(decimal)"/>
|
||||
public static Vector3 Floor(this Vector3 vec) {
|
||||
return new Vector3(vec.X.Floor(), vec.Y.Floor(), vec.Z.Floor());
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Math.Floor(decimal)"/>
|
||||
public static Vector4 Floor(this Vector4 vec) {
|
||||
return new Vector4(vec.X.Floor(), vec.Y.Floor(), vec.Z.Floor(), vec.W.Floor());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies a point by a given scalar.
|
||||
/// </summary>
|
||||
/// <param name="point">The point</param>
|
||||
/// <param name="f">The scalar</param>
|
||||
/// <returns>The point, multiplied by the scalar memberwise</returns>
|
||||
public static Point Multiply(this Point point, float f) {
|
||||
return new Point((point.X * f).Floor(), (point.Y * f).Floor());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides a point by a given scalar.
|
||||
/// </summary>
|
||||
/// <param name="point">The point</param>
|
||||
/// <param name="f">The scalar</param>
|
||||
/// <returns>The point, divided by the scalar memberwise</returns>
|
||||
public static Point Divide(this Point point, float f) {
|
||||
return new Point((point.X / f).Floor(), (point.Y / f).Floor());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a point by a given matrix.
|
||||
/// </summary>
|
||||
/// <param name="position">The point</param>
|
||||
/// <param name="matrix">The matrix</param>
|
||||
/// <returns>The point, transformed by the matrix</returns>
|
||||
public static Point Transform(this Point position, Matrix matrix) {
|
||||
return new Point(
|
||||
(position.X * matrix.M11 + position.Y * matrix.M21 + matrix.M41).Floor(),
|
||||
(position.X * matrix.M12 + position.Y * matrix.M22 + matrix.M42).Floor());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of the given rectangle, moved by the given point.
|
||||
/// The rectangle's size remains unchanged.
|
||||
/// </summary>
|
||||
/// <param name="rect">The rectangle to move</param>
|
||||
/// <param name="offset">The amount to move by</param>
|
||||
/// <returns>The moved rectangle</returns>
|
||||
public static Rectangle OffsetCopy(this Rectangle rect, Point offset) {
|
||||
rect.X += offset.X;
|
||||
rect.Y += offset.Y;
|
||||
return rect;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="OffsetCopy(Microsoft.Xna.Framework.Rectangle,Microsoft.Xna.Framework.Point)"/>
|
||||
public static RectangleF OffsetCopy(this RectangleF rect, Vector2 offset) {
|
||||
rect.X += offset.X;
|
||||
rect.Y += offset.Y;
|
||||
return rect;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shrinks the rectangle by the given padding, causing its size to decrease by twice the amount and its position to be moved inwards by the amount.
|
||||
/// </summary>
|
||||
/// <param name="rect">The rectangle to shrink</param>
|
||||
/// <param name="padding">The padding to shrink by</param>
|
||||
/// <returns>The shrunk rectangle</returns>
|
||||
public static Rectangle Shrink(this Rectangle rect, Point padding) {
|
||||
rect.X += padding.X;
|
||||
rect.Y += padding.Y;
|
||||
|
@ -75,6 +122,7 @@ namespace MLEM.Extensions {
|
|||
return rect;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Shrink(Microsoft.Xna.Framework.Rectangle,Microsoft.Xna.Framework.Point)"/>
|
||||
public static RectangleF Shrink(this RectangleF rect, Vector2 padding) {
|
||||
rect.X += padding.X;
|
||||
rect.Y += padding.Y;
|
||||
|
@ -83,6 +131,7 @@ namespace MLEM.Extensions {
|
|||
return rect;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Shrink(Microsoft.Xna.Framework.Rectangle,Microsoft.Xna.Framework.Point)"/>
|
||||
public static RectangleF Shrink(this RectangleF rect, Padding padding) {
|
||||
rect.X += padding.Left;
|
||||
rect.Y += padding.Top;
|
||||
|
|
|
@ -5,14 +5,32 @@ using System.Linq;
|
|||
namespace MLEM.Extensions {
|
||||
public static class RandomExtensions {
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random entry from the given list with uniform chance.
|
||||
/// </summary>
|
||||
/// <param name="random">The random</param>
|
||||
/// <param name="entries">The entries to choose from</param>
|
||||
/// <typeparam name="T">The entries' type</typeparam>
|
||||
/// <returns>A random entry</returns>
|
||||
public static T GetRandomEntry<T>(this Random random, params T[] entries) {
|
||||
return entries[random.Next(entries.Length)];
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="GetRandomEntry{T}(System.Random,T[])"/>
|
||||
public static T GetRandomEntry<T>(this Random random, IList<T> entries) {
|
||||
return entries[random.Next(entries.Count)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random entry from the given list based on the specified weight function.
|
||||
/// A higher weight for an entry increases its likeliness of being picked.
|
||||
/// </summary>
|
||||
/// <param name="random">The random</param>
|
||||
/// <param name="entries">The entries to choose from</param>
|
||||
/// <param name="weightFunc">A function that applies weight to each entry</param>
|
||||
/// <typeparam name="T">The entries' type</typeparam>
|
||||
/// <returns>A random entry, based on the entries' weight</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">If the weight function returns different weights for the same entry</exception>
|
||||
public static T GetRandomWeightedEntry<T>(this Random random, IList<T> entries, Func<T, int> weightFunc) {
|
||||
var totalWeight = entries.Sum(weightFunc);
|
||||
var goalWeight = random.Next(totalWeight);
|
||||
|
|
|
@ -8,6 +8,12 @@ namespace MLEM.Extensions {
|
|||
|
||||
private static Texture2D blankTexture;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a 1x1 pixel white texture that can be used for drawing solid color shapes.
|
||||
/// This texture is automatically disposed of when the batch is disposed.
|
||||
/// </summary>
|
||||
/// <param name="batch">The sprite batch</param>
|
||||
/// <returns>A 1x1 pixel white texture</returns>
|
||||
public static Texture2D GetBlankTexture(this SpriteBatch batch) {
|
||||
if (blankTexture == null) {
|
||||
blankTexture = new Texture2D(batch.GraphicsDevice, 1, 1);
|
||||
|
@ -22,6 +28,13 @@ namespace MLEM.Extensions {
|
|||
return blankTexture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a <see cref="NinePatch"/> that has a texture with a given color and outline color
|
||||
/// </summary>
|
||||
/// <param name="batch">The sprite batch</param>
|
||||
/// <param name="color">The fill color of the texture</param>
|
||||
/// <param name="outlineColor">The outline color of the texture</param>
|
||||
/// <returns>A <see cref="NinePatch"/> containing a 3x3 texture with an outline</returns>
|
||||
public static NinePatch GenerateTexture(this SpriteBatch batch, Color color, Color? outlineColor = null) {
|
||||
var outli = outlineColor ?? Color.Black;
|
||||
var tex = new Texture2D(batch.GraphicsDevice, 3, 3);
|
||||
|
@ -39,16 +52,19 @@ namespace MLEM.Extensions {
|
|||
return new NinePatch(tex, 1);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Rectangle?,Color,float,Vector2,SpriteEffects,float)"/>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) {
|
||||
var source = sourceRectangle ?? new Rectangle(0, 0, texture.Width, texture.Height);
|
||||
var scale = new Vector2(1F / source.Width, 1F / source.Height) * destinationRectangle.Size;
|
||||
batch.Draw(texture, destinationRectangle.Location, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Rectangle?,Color)"/>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color) {
|
||||
batch.Draw(texture, destinationRectangle, sourceRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Color)"/>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Color color) {
|
||||
batch.Draw(texture, destinationRectangle, null, color);
|
||||
}
|
||||
|
|
|
@ -5,38 +5,67 @@ using Microsoft.Xna.Framework;
|
|||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace MLEM.Font {
|
||||
/// <summary>
|
||||
/// Represents a font with additional abilities.
|
||||
/// <seealso cref="GenericSpriteFont"/>
|
||||
/// </summary>
|
||||
public abstract class GenericFont {
|
||||
|
||||
/// <summary>
|
||||
/// The bold version of this font.
|
||||
/// </summary>
|
||||
public abstract GenericFont Bold { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The italic version of this font.
|
||||
/// </summary>
|
||||
public abstract GenericFont Italic { get; }
|
||||
|
||||
///<inheritdoc cref="SpriteFont.LineSpacing"/>
|
||||
public abstract float LineHeight { get; }
|
||||
|
||||
///<inheritdoc cref="SpriteFont.MeasureString(string)"/>
|
||||
public abstract Vector2 MeasureString(string text);
|
||||
|
||||
///<inheritdoc cref="SpriteFont.MeasureString(StringBuilder)"/>
|
||||
public abstract Vector2 MeasureString(StringBuilder text);
|
||||
|
||||
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
|
||||
public abstract void DrawString(SpriteBatch batch, string text, Vector2 position, Color color);
|
||||
|
||||
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
|
||||
public abstract void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth);
|
||||
|
||||
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
|
||||
public abstract void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
|
||||
|
||||
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
|
||||
public abstract void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color);
|
||||
|
||||
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
|
||||
public abstract void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth);
|
||||
|
||||
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
|
||||
public abstract void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a string with the given text alignment.
|
||||
/// </summary>
|
||||
/// <param name="batch">The sprite batch to use</param>
|
||||
/// <param name="text">The string to draw</param>
|
||||
/// <param name="position">The position of the top left corner of the string</param>
|
||||
/// <param name="align">The alignment to use</param>
|
||||
/// <param name="color">The color to use</param>
|
||||
public void DrawString(SpriteBatch batch, string text, Vector2 position, TextAlign align, Color color) {
|
||||
this.DrawString(batch, text, position, align, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
///<inheritdoc cref="DrawString(SpriteBatch,string,Vector2,TextAlign,Color)"/>
|
||||
public void DrawString(SpriteBatch batch, string text, Vector2 position, TextAlign align, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) {
|
||||
this.DrawString(batch, text, position, align, color, rotation, origin, new Vector2(scale), effects, layerDepth);
|
||||
}
|
||||
|
||||
///<inheritdoc cref="DrawString(SpriteBatch,string,Vector2,TextAlign,Color)"/>
|
||||
public void DrawString(SpriteBatch batch, string text, Vector2 position, TextAlign align, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
|
||||
switch (align) {
|
||||
case TextAlign.Center:
|
||||
|
@ -53,6 +82,16 @@ namespace MLEM.Font {
|
|||
this.DrawString(batch, text, position, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Truncates a string to a given width. If the string's displayed area is larger than the maximum width, the string is cut off.
|
||||
/// Optionally, the string can be cut off a bit sooner, adding the <see cref="ellipsis"/> at the end instead.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to truncate</param>
|
||||
/// <param name="width">The maximum width, in display pixels based on the font and scale</param>
|
||||
/// <param name="scale">The scale to use for width measurements</param>
|
||||
/// <param name="fromBack">If the string should be truncated from the back rather than the front</param>
|
||||
/// <param name="ellipsis">The characters to add to the end of the string if it is too long</param>
|
||||
/// <returns>The truncated string, or the same string if it is shorter than the maximum width</returns>
|
||||
public string TruncateString(string text, float width, float scale, bool fromBack = false, string ellipsis = "") {
|
||||
var total = new StringBuilder();
|
||||
var ellipsisWidth = this.MeasureString(ellipsis).X * scale;
|
||||
|
@ -74,6 +113,14 @@ namespace MLEM.Font {
|
|||
return total.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Splits a string to a given maximum width, adding newline characters between each line.
|
||||
/// Also splits long words.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to split into multiple lines</param>
|
||||
/// <param name="width">The maximum width that each line should have</param>
|
||||
/// <param name="scale">The scale to use for width measurements</param>
|
||||
/// <returns>The split string, containing newline characters at each new line</returns>
|
||||
public string SplitString(string text, float width, float scale) {
|
||||
var total = new StringBuilder();
|
||||
foreach (var line in text.Split('\n')) {
|
||||
|
@ -109,6 +156,12 @@ namespace MLEM.Font {
|
|||
return total.ToString(0, total.Length - 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string made up of the given content characters that is the given length long when displayed.
|
||||
/// </summary>
|
||||
/// <param name="width">The width that the string should have if the scale is 1</param>
|
||||
/// <param name="content">The content that the string should contain. Defaults to a space.</param>
|
||||
/// <returns></returns>
|
||||
public string GetWidthString(float width, char content = ' ') {
|
||||
var strg = content.ToString();
|
||||
while (this.MeasureString(strg).X < width)
|
||||
|
|
|
@ -5,47 +5,66 @@ using Microsoft.Xna.Framework.Graphics;
|
|||
using MLEM.Extensions;
|
||||
|
||||
namespace MLEM.Font {
|
||||
/// <inheritdoc/>
|
||||
public class GenericSpriteFont : GenericFont {
|
||||
|
||||
public readonly SpriteFont Font;
|
||||
/// <inheritdoc/>
|
||||
public override GenericFont Bold { get; }
|
||||
/// <inheritdoc/>
|
||||
public override GenericFont Italic { get; }
|
||||
/// <inheritdoc/>
|
||||
public override float LineHeight => this.Font.LineSpacing;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new generic font using <see cref="SpriteFont"/>.
|
||||
/// Optionally, a bold and italic version of the font can be supplied.
|
||||
/// </summary>
|
||||
/// <param name="font">The font to wrap</param>
|
||||
/// <param name="bold">A bold version of the font</param>
|
||||
/// <param name="italic">An italic version of the font</param>
|
||||
public GenericSpriteFont(SpriteFont font, SpriteFont bold = null, SpriteFont italic = null) {
|
||||
this.Font = font;
|
||||
this.Bold = bold != null ? new GenericSpriteFont(bold) : this;
|
||||
this.Italic = italic != null ? new GenericSpriteFont(italic) : this;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Vector2 MeasureString(string text) {
|
||||
return this.Font.MeasureString(text);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Vector2 MeasureString(StringBuilder text) {
|
||||
return this.Font.MeasureString(text);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void DrawString(SpriteBatch batch, string text, Vector2 position, Color color) {
|
||||
batch.DrawString(this.Font, text, position, color);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) {
|
||||
batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
|
||||
batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color) {
|
||||
batch.DrawString(this.Font, text, position, color);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) {
|
||||
batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
|
||||
batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue