From c76357a9e3db4ff70ac7f303e9756ea4f37b3c01 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Tue, 21 Dec 2021 20:12:15 +0100 Subject: [PATCH] Allow storing multiple texture regions per SpriteAnimation frame --- CHANGELOG.md | 1 + MLEM/Animations/SpriteAnimation.cs | 49 +++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 988eb2a..0efd5b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Improvements - Throw an exception when text formatter macros resolve recursively too many times - Allow using StaticSpriteBatch for AutoTiling - Made TextFormatter string size based on the currently active font rather than the default one +- Allow storing multiple texture regions per SpriteAnimation frame Fixes - Fixed some end-of-line inconsistencies when using the Right text alignment diff --git a/MLEM/Animations/SpriteAnimation.cs b/MLEM/Animations/SpriteAnimation.cs index a85af4c..f72e09b 100644 --- a/MLEM/Animations/SpriteAnimation.cs +++ b/MLEM/Animations/SpriteAnimation.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Misc; @@ -36,10 +38,16 @@ namespace MLEM.Animations { } } /// - /// The texture region that the animation's has + /// The texture region that this animation's should render. + /// If there are multiple regions, should be used instead. /// public TextureRegion CurrentRegion => this.CurrentFrame.Region; /// + /// The texture regions that this animation's should render. + /// If there is only one region, can be used for convenience. + /// + public IList CurrentRegions => this.CurrentFrame.Regions; + /// /// The total amount of time that this animation has. /// This is auatomatically calculated based on the frame time of each frame. /// @@ -83,6 +91,8 @@ namespace MLEM.Animations { /// /// The frames this animation should have public SpriteAnimation(params AnimationFrame[] frames) { + if (frames.Length <= 0) + throw new ArgumentException("Cannot create a sprite animation without any frames"); this.frames = frames; foreach (var frame in frames) this.TotalTime += frame.Seconds; @@ -94,7 +104,16 @@ namespace MLEM.Animations { /// The amount of time that each frame should last for /// The texture regions that should make up this animation public SpriteAnimation(double timePerFrame, params TextureRegion[] regions) - : this(Array.ConvertAll(regions, region => new AnimationFrame(region, timePerFrame))) { + : this(Array.ConvertAll(regions, r => new AnimationFrame(timePerFrame, r))) { + } + + /// + /// Creates a new sprite animation that contains the given texture region arrays as frames, where each frame represents one set of texture regions. + /// + /// The amount of time that each frame should last for + /// The texture regions that should make up this animation + public SpriteAnimation(double timePerFrame, params TextureRegion[][] regions) : + this(Array.ConvertAll(regions, r => new AnimationFrame(timePerFrame, r))) { } /// @@ -103,8 +122,8 @@ namespace MLEM.Animations { /// The amount of time that each frame should last for /// The texture that the regions should come from /// The texture regions that should make up this animation - public SpriteAnimation(double timePerFrame, Texture2D texture, params Rectangle[] regions) - : this(timePerFrame, Array.ConvertAll(regions, region => new TextureRegion(texture, region))) { + public SpriteAnimation(double timePerFrame, Texture2D texture, params Rectangle[] regions) : + this(timePerFrame, Array.ConvertAll(regions, r => new TextureRegion(texture, r))) { } /// @@ -156,21 +175,29 @@ namespace MLEM.Animations { public class AnimationFrame { /// - /// The texture region that this frame should render + /// The texture regions that this frame should render. + /// If there is only one region, can be used for convenience. /// - public readonly TextureRegion Region; + public readonly IList Regions; /// - /// The total amount of seconds that this frame should last for + /// The total amount of seconds that this frame should last for. /// public readonly double Seconds; + /// + /// The texture region that this frame should render. + /// If there are multiple regions, should be used instead. + /// + public TextureRegion Region => this.Regions[0]; /// - /// Creates a new animation frame based on a texture region and a time + /// Creates a new animation frame based on a set of texture regions and a time. /// - /// The texture region that this frame should render + /// The texture regions that this frame should render /// The total amount of seconds that this frame should last for - public AnimationFrame(TextureRegion region, double seconds) { - this.Region = region; + public AnimationFrame(double seconds, params TextureRegion[] regions) { + if (regions.Length <= 0) + throw new ArgumentException("Cannot create an animation frame without any regions"); + this.Regions = new ReadOnlyCollection(regions); this.Seconds = seconds; }