From e20a51ef23200089afa7e877232e0e60a9b9894a Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sat, 4 Jan 2020 00:27:45 +0100 Subject: [PATCH] allowed formatting codes to contain sprite animations --- Demos/UiDemo.cs | 7 ++++++- MLEM/Animations/SpriteAnimation.cs | 15 +++++++++------ MLEM/Animations/SpriteAnimationGroup.cs | 2 +- MLEM/Formatting/FormattingCode.cs | 11 ++++++++--- MLEM/Formatting/TextFormatting.cs | 5 +++-- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/Demos/UiDemo.cs b/Demos/UiDemo.cs index 23d3c1d..765e567 100644 --- a/Demos/UiDemo.cs +++ b/Demos/UiDemo.cs @@ -4,6 +4,7 @@ using System.Linq; using Coroutine; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using MLEM.Animations; using MLEM.Extensions; using MLEM.Font; using MLEM.Formatting; @@ -96,7 +97,11 @@ namespace Demos { // note that all added formatting codes need to be lowercase, while their casing doesn't matter when used TextFormatting.FormattingCodes["grass"] = new FormattingCode(image.Texture); TextFormatting.FormattingCodes["tree"] = new FormattingCode(tree); - root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "Additionally, you can create custom formatting codes that contain [Grass] images! Note that these images have to be square, or [Tree] bad things happen.")); + // formatting codes can also be sprite animations! + var atlas = new UniformTextureAtlas(LoadContent("Textures/Anim"), 4, 4); + TextFormatting.FormattingCodes["walk"] = new FormattingCode(new SpriteAnimation(0.2F, atlas[0, 0], atlas[0, 1], atlas[0, 2], atlas[0, 3])); + + root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "Additionally, you can create custom formatting codes that contain [Grass] images or [Walk] sprite animations! Note that these images have to be square, or [Tree] bad things happen.")); var animatedPar = root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "Defining text animations as formatting codes is also possible, including [Wobbly]wobbly text[Unanimated] as well as a [Typing]dialogue-esc typing effect by default. Of course, more animations can be added though.")); root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 10), "Reset Typing Animation") { diff --git a/MLEM/Animations/SpriteAnimation.cs b/MLEM/Animations/SpriteAnimation.cs index 3cd76b9..43de748 100644 --- a/MLEM/Animations/SpriteAnimation.cs +++ b/MLEM/Animations/SpriteAnimation.cs @@ -39,19 +39,22 @@ namespace MLEM.Animations { this.TotalTime += frame.Seconds; } - public SpriteAnimation(float timePerFrame, params TextureRegion[] regions) + public SpriteAnimation(double timePerFrame, params TextureRegion[] regions) : this(Array.ConvertAll(regions, region => new AnimationFrame(region, timePerFrame))) { } - public SpriteAnimation(float timePerFrame, Texture2D texture, params Rectangle[] regions) + public SpriteAnimation(double timePerFrame, Texture2D texture, params Rectangle[] regions) : this(timePerFrame, Array.ConvertAll(regions, region => new TextureRegion(texture, region))) { } public void Update(GameTime time) { + this.SetTime(this.TimeIntoAnimation + time.ElapsedGameTime.TotalSeconds); + } + + public void SetTime(double totalTime) { if (this.IsFinished || this.IsPaused) return; - - this.TimeIntoAnimation += time.ElapsedGameTime.TotalSeconds; + this.TimeIntoAnimation = totalTime; if (this.TimeIntoAnimation >= this.TotalTime) { if (!this.IsLooping) { this.IsFinished = true; @@ -75,9 +78,9 @@ namespace MLEM.Animations { public class AnimationFrame { public readonly TextureRegion Region; - public readonly float Seconds; + public readonly double Seconds; - public AnimationFrame(TextureRegion region, float seconds) { + public AnimationFrame(TextureRegion region, double seconds) { this.Region = region; this.Seconds = seconds; } diff --git a/MLEM/Animations/SpriteAnimationGroup.cs b/MLEM/Animations/SpriteAnimationGroup.cs index b0a4bcd..4a8651b 100644 --- a/MLEM/Animations/SpriteAnimationGroup.cs +++ b/MLEM/Animations/SpriteAnimationGroup.cs @@ -41,7 +41,7 @@ namespace MLEM.Animations { return this.animations.Find(anim => anim.Animation.Name == name)?.Animation; } - private void FindAnimationToPlay() { + public void FindAnimationToPlay() { ConditionedAnimation animToPlay = null; if (this.CurrAnimation != null && this.CurrAnimation.ShouldPlay()) animToPlay = this.CurrAnimation; diff --git a/MLEM/Formatting/FormattingCode.cs b/MLEM/Formatting/FormattingCode.cs index 2a418a1..46a4d05 100644 --- a/MLEM/Formatting/FormattingCode.cs +++ b/MLEM/Formatting/FormattingCode.cs @@ -1,4 +1,5 @@ using Microsoft.Xna.Framework; +using MLEM.Animations; using MLEM.Font; using MLEM.Textures; @@ -8,7 +9,7 @@ namespace MLEM.Formatting { public readonly Type CodeType; public readonly Color Color; public readonly TextStyle Style; - public readonly TextureRegion Icon; + public readonly SpriteAnimation Icon; public readonly TextAnimation.DrawCharacter Animation; public FormattingCode(Color color) { @@ -21,7 +22,11 @@ namespace MLEM.Formatting { this.CodeType = Type.Style; } - public FormattingCode(TextureRegion icon) { + public FormattingCode(TextureRegion icon) : + this(new SpriteAnimation(0, icon)) { + } + + public FormattingCode(SpriteAnimation icon) { this.Icon = icon; this.CodeType = Type.Icon; } @@ -31,7 +36,7 @@ namespace MLEM.Formatting { this.CodeType = Type.Animation; } - public string GetReplacementString(IGenericFont font) { + public virtual string GetReplacementString(IGenericFont font) { return this.CodeType == Type.Icon ? TextFormatting.GetOneEmString(font) : string.Empty; } diff --git a/MLEM/Formatting/TextFormatting.cs b/MLEM/Formatting/TextFormatting.cs index 4f450b9..c95b869 100644 --- a/MLEM/Formatting/TextFormatting.cs +++ b/MLEM/Formatting/TextFormatting.cs @@ -5,6 +5,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Extensions; using MLEM.Font; +using MLEM.Misc; using MLEM.Textures; namespace MLEM.Formatting { @@ -107,8 +108,8 @@ namespace MLEM.Formatting { currStyle = code.Style; break; case FormattingCode.Type.Icon: - var iconSc = new Vector2(1F / code.Icon.Width, 1F / code.Icon.Height) * regularFont.LineHeight * scale; - batch.Draw(code.Icon, pos + innerOffset, color, 0, Vector2.Zero, iconSc, SpriteEffects.None, depth); + code.Icon.SetTime(timeIntoAnimation.TotalSeconds % code.Icon.TotalTime); + batch.Draw(code.Icon.CurrentRegion, new RectangleF(pos + innerOffset, new Vector2(regularFont.LineHeight * scale)), color, 0, Vector2.Zero, SpriteEffects.None, depth); break; case FormattingCode.Type.Animation: currAnim = code.Animation;