mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-26 14:38:34 +01:00
improved SpriteAnimationGroup performance
This commit is contained in:
parent
c31e196071
commit
b5bee0facb
1 changed files with 38 additions and 30 deletions
|
@ -11,23 +11,15 @@ namespace MLEM.Animations {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SpriteAnimationGroup : GenericDataHolder {
|
public class SpriteAnimationGroup : GenericDataHolder {
|
||||||
|
|
||||||
private readonly List<ConditionedAnimation> animations = new List<ConditionedAnimation>();
|
|
||||||
private ConditionedAnimation currAnimation;
|
|
||||||
private ConditionedAnimation CurrAnimation {
|
|
||||||
get {
|
|
||||||
if (this.isDirty) {
|
|
||||||
this.isDirty = false;
|
|
||||||
this.animations.Sort((a1, a2) => a2.Priority.CompareTo(a1.Priority));
|
|
||||||
this.FindAnimationToPlay();
|
|
||||||
}
|
|
||||||
return this.currAnimation;
|
|
||||||
}
|
|
||||||
set => this.currAnimation = value;
|
|
||||||
}
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the animation that is currently playing.
|
/// Returns the animation that is currently playing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SpriteAnimation CurrentAnimation => this.CurrAnimation?.Animation;
|
public SpriteAnimation CurrentAnimation {
|
||||||
|
get {
|
||||||
|
this.SortAnimationsIfDirty(true);
|
||||||
|
return this.currentAnimation?.Animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the frame that <see cref="CurrentAnimation"/> is displaying.
|
/// Returns the frame that <see cref="CurrentAnimation"/> is displaying.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -40,11 +32,6 @@ namespace MLEM.Animations {
|
||||||
/// Returns the <see cref="CurrentAnimation"/>'s <see cref="SpriteAnimation.CurrentRegions"/>.
|
/// Returns the <see cref="CurrentAnimation"/>'s <see cref="SpriteAnimation.CurrentRegions"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<TextureRegion> CurrentRegions => this.CurrentAnimation?.CurrentRegions;
|
public IList<TextureRegion> CurrentRegions => this.CurrentAnimation?.CurrentRegions;
|
||||||
/// <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"/>
|
/// <inheritdoc cref="SpriteAnimation.SpeedMultiplier"/>
|
||||||
public float SpeedMultiplier {
|
public float SpeedMultiplier {
|
||||||
set {
|
set {
|
||||||
|
@ -53,6 +40,15 @@ namespace MLEM.Animations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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 readonly List<ConditionedAnimation> animations = new List<ConditionedAnimation>();
|
||||||
|
private ConditionedAnimation currentAnimation;
|
||||||
|
private bool animationsDirty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="SpriteAnimation"/> to this group.
|
/// Adds a <see cref="SpriteAnimation"/> to this group.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -62,7 +58,7 @@ namespace MLEM.Animations {
|
||||||
/// <returns>This group, for chaining</returns>
|
/// <returns>This group, for chaining</returns>
|
||||||
public SpriteAnimationGroup Add(SpriteAnimation anim, Func<bool> condition, int priority = 0) {
|
public SpriteAnimationGroup Add(SpriteAnimation anim, Func<bool> condition, int priority = 0) {
|
||||||
this.animations.Add(new ConditionedAnimation(anim, condition, priority));
|
this.animations.Add(new ConditionedAnimation(anim, condition, priority));
|
||||||
this.isDirty = true;
|
this.animationsDirty = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +70,8 @@ namespace MLEM.Animations {
|
||||||
/// <inheritdoc cref="SpriteAnimation.Update(TimeSpan)"/>
|
/// <inheritdoc cref="SpriteAnimation.Update(TimeSpan)"/>
|
||||||
public void Update(TimeSpan elapsed) {
|
public void Update(TimeSpan elapsed) {
|
||||||
this.FindAnimationToPlay();
|
this.FindAnimationToPlay();
|
||||||
if (this.CurrAnimation != null)
|
if (this.CurrentAnimation != null)
|
||||||
this.CurrAnimation.Animation.Update(elapsed);
|
this.CurrentAnimation.Update(elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -88,25 +84,37 @@ namespace MLEM.Animations {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FindAnimationToPlay() {
|
private void FindAnimationToPlay() {
|
||||||
|
this.SortAnimationsIfDirty(false);
|
||||||
|
|
||||||
ConditionedAnimation animToPlay = null;
|
ConditionedAnimation animToPlay = null;
|
||||||
if (this.CurrAnimation != null && this.CurrAnimation.ShouldPlay())
|
if (this.currentAnimation != null && this.currentAnimation.ShouldPlay())
|
||||||
animToPlay = this.CurrAnimation;
|
animToPlay = this.currentAnimation;
|
||||||
|
|
||||||
foreach (var anim in this.animations) {
|
foreach (var anim in this.animations) {
|
||||||
// if we find an animation with a lower priority then it means we can break
|
// if we find an animation with a lower priority then it means we can break since the list is sorted by priority
|
||||||
// because the list is sorted by priority
|
if (animToPlay != null && anim.Priority <= animToPlay.Priority)
|
||||||
if (animToPlay != null && anim.Priority < animToPlay.Priority)
|
|
||||||
break;
|
break;
|
||||||
if (anim.ShouldPlay())
|
if (anim.ShouldPlay())
|
||||||
animToPlay = anim;
|
animToPlay = anim;
|
||||||
}
|
}
|
||||||
if (animToPlay != this.CurrAnimation) {
|
|
||||||
this.OnAnimationChanged?.Invoke(this.CurrAnimation?.Animation, animToPlay?.Animation);
|
if (animToPlay != this.currentAnimation) {
|
||||||
this.CurrAnimation = animToPlay;
|
this.OnAnimationChanged?.Invoke(this.currentAnimation?.Animation, animToPlay?.Animation);
|
||||||
|
this.currentAnimation = animToPlay;
|
||||||
if (animToPlay != null)
|
if (animToPlay != null)
|
||||||
animToPlay.Animation.Restart();
|
animToPlay.Animation.Restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SortAnimationsIfDirty(bool findAnimationToPlay) {
|
||||||
|
if (this.animationsDirty) {
|
||||||
|
this.animationsDirty = false;
|
||||||
|
this.animations.Sort((a1, a2) => a2.Priority.CompareTo(a1.Priority));
|
||||||
|
if (findAnimationToPlay)
|
||||||
|
this.FindAnimationToPlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A callback delegate for when a <see cref="SpriteAnimationGroup"/>'s current animation changed.
|
/// A callback delegate for when a <see cref="SpriteAnimationGroup"/>'s current animation changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in a new issue