1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-01 21:03:38 +02:00
MLEM/MLEM/Animations/SpriteAnimation.cs

86 lines
3 KiB
C#
Raw Normal View History

2019-08-14 19:07:23 +02:00
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Textures;
namespace MLEM.Animations {
public class SpriteAnimation {
private AnimationFrame[] frames;
public AnimationFrame this[int index] => this.frames[index];
public AnimationFrame CurrentFrame {
get {
// we might have overshot the end time by a little bit, so just return the last frame
if (this.TimeIntoAnimation >= this.TotalTime)
return this.frames[this.frames.Length - 1];
2019-08-14 19:07:23 +02:00
var accum = 0D;
foreach (var frame in this.frames) {
accum += frame.Seconds;
if (accum >= this.TimeIntoAnimation)
return frame;
}
// if we're here then the time is negative for some reason, so just return the first frame
return this.frames[0];
2019-08-14 19:07:23 +02:00
}
}
public TextureRegion CurrentRegion => this.CurrentFrame.Region;
public readonly double TotalTime;
public double TimeIntoAnimation { get; private set; }
public bool IsFinished { get; private set; }
public string Name;
public float SpeedMultiplier = 1;
2019-08-14 19:07:23 +02:00
public bool IsLooping = true;
public Completed OnCompleted;
public bool IsPaused;
public SpriteAnimation(params AnimationFrame[] frames) {
this.frames = frames;
foreach (var frame in frames)
this.TotalTime += frame.Seconds;
}
public SpriteAnimation(double timePerFrame, params TextureRegion[] regions)
2019-08-14 19:07:23 +02:00
: this(Array.ConvertAll(regions, region => new AnimationFrame(region, timePerFrame))) {
}
public SpriteAnimation(double timePerFrame, Texture2D texture, params Rectangle[] regions)
2019-08-14 19:07:23 +02:00
: this(timePerFrame, Array.ConvertAll(regions, region => new TextureRegion(texture, region))) {
}
public void Update(GameTime time) {
if (this.IsFinished || this.IsPaused)
return;
this.TimeIntoAnimation += time.ElapsedGameTime.TotalSeconds * this.SpeedMultiplier;
2019-08-14 19:07:23 +02:00
if (this.TimeIntoAnimation >= this.TotalTime) {
if (!this.IsLooping) {
this.IsFinished = true;
} else {
this.Restart();
}
this.OnCompleted?.Invoke(this);
}
}
public void Restart() {
this.TimeIntoAnimation = 0;
this.IsFinished = false;
this.IsPaused = false;
}
public delegate void Completed(SpriteAnimation animation);
}
public class AnimationFrame {
public readonly TextureRegion Region;
public readonly double Seconds;
2019-08-14 19:07:23 +02:00
public AnimationFrame(TextureRegion region, double seconds) {
2019-08-14 19:07:23 +02:00
this.Region = region;
this.Seconds = seconds;
}
}
}