2019-08-14 19:07:23 +02:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
using MLEM.Textures;
|
|
|
|
|
|
|
|
namespace MLEM.Animations {
|
|
|
|
public class SpriteAnimationGroup {
|
|
|
|
|
|
|
|
private readonly List<ConditionedAnimation> animations = new List<ConditionedAnimation>();
|
|
|
|
private ConditionedAnimation currAnimation;
|
2019-09-30 20:55:50 +02:00
|
|
|
private ConditionedAnimation CurrAnimation {
|
|
|
|
get {
|
|
|
|
if (this.isDirty) {
|
|
|
|
this.isDirty = false;
|
|
|
|
this.animations.Sort((a1, a2) => a1.Priority.CompareTo(a2.Priority));
|
|
|
|
this.FindAnimationToPlay();
|
|
|
|
}
|
|
|
|
return this.currAnimation;
|
|
|
|
}
|
|
|
|
set => this.currAnimation = value;
|
|
|
|
}
|
|
|
|
public SpriteAnimation CurrentAnimation => this.CurrAnimation?.Animation;
|
2019-08-21 17:04:20 +02:00
|
|
|
public AnimationFrame CurrentFrame => this.CurrentAnimation?.CurrentFrame;
|
|
|
|
public TextureRegion CurrentRegion => this.CurrentAnimation?.CurrentRegion;
|
2019-08-21 20:25:32 +02:00
|
|
|
public AnimationChanged OnAnimationChanged;
|
2019-09-30 20:55:50 +02:00
|
|
|
private bool isDirty;
|
2019-08-14 19:07:23 +02:00
|
|
|
|
2019-08-21 20:25:32 +02:00
|
|
|
public SpriteAnimationGroup Add(SpriteAnimation anim, Func<bool> condition, int priority = 0) {
|
|
|
|
this.animations.Add(new ConditionedAnimation(anim, condition, priority));
|
2019-09-30 20:55:50 +02:00
|
|
|
this.isDirty = true;
|
2019-08-14 19:07:23 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Update(GameTime time) {
|
2019-09-30 20:55:50 +02:00
|
|
|
this.FindAnimationToPlay();
|
|
|
|
if (this.CurrAnimation != null)
|
|
|
|
this.CurrAnimation.Animation.Update(time);
|
|
|
|
}
|
|
|
|
|
|
|
|
public SpriteAnimation ByName(string name) {
|
|
|
|
return this.animations.Find(anim => anim.Animation.Name == name)?.Animation;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void FindAnimationToPlay() {
|
2019-08-21 20:25:32 +02:00
|
|
|
ConditionedAnimation animToPlay = null;
|
2019-09-30 20:55:50 +02:00
|
|
|
if (this.CurrAnimation != null && this.CurrAnimation.ShouldPlay())
|
|
|
|
animToPlay = this.CurrAnimation;
|
2019-08-21 20:25:32 +02:00
|
|
|
foreach (var anim in this.animations) {
|
|
|
|
// if we find an animation with a lower priority then it means we can break
|
|
|
|
// because the list is sorted by priority
|
|
|
|
if (animToPlay != null && anim.Priority < animToPlay.Priority)
|
|
|
|
break;
|
|
|
|
if (anim.ShouldPlay())
|
|
|
|
animToPlay = anim;
|
2019-08-14 19:07:23 +02:00
|
|
|
}
|
2019-09-30 20:55:50 +02:00
|
|
|
if (animToPlay != this.CurrAnimation) {
|
|
|
|
this.OnAnimationChanged?.Invoke(this.CurrAnimation?.Animation, animToPlay?.Animation);
|
|
|
|
this.CurrAnimation = animToPlay;
|
2019-08-21 20:25:32 +02:00
|
|
|
if (animToPlay != null)
|
|
|
|
animToPlay.Animation.Restart();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public delegate void AnimationChanged(SpriteAnimation oldAnim, SpriteAnimation newAnim);
|
|
|
|
|
2019-08-14 19:07:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
internal class ConditionedAnimation {
|
|
|
|
|
|
|
|
public readonly SpriteAnimation Animation;
|
|
|
|
public readonly Func<bool> ShouldPlay;
|
2019-08-21 20:25:32 +02:00
|
|
|
public readonly int Priority;
|
2019-08-14 19:07:23 +02:00
|
|
|
|
2019-08-21 20:25:32 +02:00
|
|
|
public ConditionedAnimation(SpriteAnimation animation, Func<bool> shouldPlay, int priority) {
|
2019-08-14 19:07:23 +02:00
|
|
|
this.Animation = animation;
|
|
|
|
this.ShouldPlay = shouldPlay;
|
2019-08-21 20:25:32 +02:00
|
|
|
this.Priority = priority;
|
2019-08-14 19:07:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|