mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 20:58:34 +01:00
added naming and priorities to animations
This commit is contained in:
parent
46a4aec1c9
commit
04b9c9e97c
4 changed files with 54 additions and 20 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
@ -17,10 +18,10 @@ namespace Demos {
|
||||||
var tex = LoadContent<Texture2D>("Textures/Anim");
|
var tex = LoadContent<Texture2D>("Textures/Anim");
|
||||||
|
|
||||||
// create the four animations by supplying the time per frame, the texture and the four regions used
|
// create the four animations by supplying the time per frame, the texture and the four regions used
|
||||||
var downAnim = new SpriteAnimation(0.2F, tex, new Rectangle(0, 0, 8, 8), new Rectangle(0, 8, 8, 8), new Rectangle(0, 16, 8, 8), new Rectangle(0, 24, 8, 8));
|
var downAnim = new SpriteAnimation(0.2F, tex, new Rectangle(0, 0, 8, 8), new Rectangle(0, 8, 8, 8), new Rectangle(0, 16, 8, 8), new Rectangle(0, 24, 8, 8)) {Name = "Down"};
|
||||||
var upAnim = new SpriteAnimation(0.2F, tex, new Rectangle(8, 0, 8, 8), new Rectangle(8, 8, 8, 8), new Rectangle(8, 16, 8, 8), new Rectangle(8, 24, 8, 8));
|
var upAnim = new SpriteAnimation(0.2F, tex, new Rectangle(8, 0, 8, 8), new Rectangle(8, 8, 8, 8), new Rectangle(8, 16, 8, 8), new Rectangle(8, 24, 8, 8)) {Name = "Up"};
|
||||||
var leftAnim = new SpriteAnimation(0.2F, tex, new Rectangle(16, 0, 8, 8), new Rectangle(16, 8, 8, 8), new Rectangle(16, 16, 8, 8), new Rectangle(16, 24, 8, 8));
|
var leftAnim = new SpriteAnimation(0.2F, tex, new Rectangle(16, 0, 8, 8), new Rectangle(16, 8, 8, 8), new Rectangle(16, 16, 8, 8), new Rectangle(16, 24, 8, 8)) {Name = "Left"};
|
||||||
var rightAnim = new SpriteAnimation(0.2F, tex, new Rectangle(24, 0, 8, 8), new Rectangle(24, 8, 8, 8), new Rectangle(24, 16, 8, 8), new Rectangle(24, 24, 8, 8));
|
var rightAnim = new SpriteAnimation(0.2F, tex, new Rectangle(24, 0, 8, 8), new Rectangle(24, 8, 8, 8), new Rectangle(24, 16, 8, 8), new Rectangle(24, 24, 8, 8)) {Name = "Right"};
|
||||||
|
|
||||||
// create a sprite animation group which manages a list of animations and figures out which one should
|
// create a sprite animation group which manages a list of animations and figures out which one should
|
||||||
// be playing right now based on supplied conditions
|
// be playing right now based on supplied conditions
|
||||||
|
@ -32,6 +33,16 @@ namespace Demos {
|
||||||
this.group.Add(upAnim, () => this.facing == 1);
|
this.group.Add(upAnim, () => this.facing == 1);
|
||||||
this.group.Add(leftAnim, () => this.facing == 2);
|
this.group.Add(leftAnim, () => this.facing == 2);
|
||||||
this.group.Add(rightAnim, () => this.facing == 3);
|
this.group.Add(rightAnim, () => this.facing == 3);
|
||||||
|
|
||||||
|
// you can also add a priority to an animation in the group (10 in this case, which is higher than the default of 0)
|
||||||
|
// if two animations' playing conditions are both true, then the one with the higher priority will be picked to play
|
||||||
|
// in this instance, a standing "animation" is displayed when we're facing down and also holding the space key
|
||||||
|
this.group.Add(new SpriteAnimation(1F, tex, new Rectangle(0, 0, 8, 8)) {Name = "DownStanding"}, () => this.facing == 0 && Input.IsKeyDown(Keys.Space), 10);
|
||||||
|
|
||||||
|
// you can also add a callback to see when the animation used changes
|
||||||
|
this.group.OnAnimationChanged += (anim, newAnim) => {
|
||||||
|
Console.WriteLine("Changing anim from " + (anim?.Name ?? "None") + " to " + (newAnim?.Name ?? "None"));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update(GameTime gameTime) {
|
protected override void Update(GameTime gameTime) {
|
||||||
|
|
|
@ -213,7 +213,7 @@ namespace MLEM.Ui.Elements {
|
||||||
|
|
||||||
this.sortedChildren.Clear();
|
this.sortedChildren.Clear();
|
||||||
this.sortedChildren.AddRange(this.Children);
|
this.sortedChildren.AddRange(this.Children);
|
||||||
this.sortedChildren.Sort((e1, e2) => e1.Priority.CompareTo(e1.Priority));
|
this.sortedChildren.Sort((e1, e2) => e1.Priority.CompareTo(e2.Priority));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,20 +10,25 @@ namespace MLEM.Animations {
|
||||||
public AnimationFrame this[int index] => this.frames[index];
|
public AnimationFrame this[int index] => this.frames[index];
|
||||||
public AnimationFrame CurrentFrame {
|
public AnimationFrame CurrentFrame {
|
||||||
get {
|
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];
|
||||||
var accum = 0D;
|
var accum = 0D;
|
||||||
foreach (var frame in this.frames) {
|
foreach (var frame in this.frames) {
|
||||||
accum += frame.Seconds;
|
accum += frame.Seconds;
|
||||||
if (accum >= this.TimeIntoAnimation)
|
if (accum >= this.TimeIntoAnimation)
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
// we might have overshot the end time by a little bit, so just return the last frame
|
// if we're here then the time is negative for some reason, so just return the first frame
|
||||||
return this.frames[this.frames.Length - 1];
|
Console.WriteLine("Test");
|
||||||
|
return this.frames[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public TextureRegion CurrentRegion => this.CurrentFrame.Region;
|
public TextureRegion CurrentRegion => this.CurrentFrame.Region;
|
||||||
public readonly double TotalTime;
|
public readonly double TotalTime;
|
||||||
public double TimeIntoAnimation { get; private set; }
|
public double TimeIntoAnimation { get; private set; }
|
||||||
public bool IsFinished { get; private set; }
|
public bool IsFinished { get; private set; }
|
||||||
|
public string Name;
|
||||||
|
|
||||||
public bool IsLooping = true;
|
public bool IsLooping = true;
|
||||||
public Completed OnCompleted;
|
public Completed OnCompleted;
|
||||||
|
|
|
@ -11,37 +11,55 @@ namespace MLEM.Animations {
|
||||||
public SpriteAnimation CurrentAnimation => this.currAnimation?.Animation;
|
public SpriteAnimation CurrentAnimation => this.currAnimation?.Animation;
|
||||||
public AnimationFrame CurrentFrame => this.CurrentAnimation?.CurrentFrame;
|
public AnimationFrame CurrentFrame => this.CurrentAnimation?.CurrentFrame;
|
||||||
public TextureRegion CurrentRegion => this.CurrentAnimation?.CurrentRegion;
|
public TextureRegion CurrentRegion => this.CurrentAnimation?.CurrentRegion;
|
||||||
|
public AnimationChanged OnAnimationChanged;
|
||||||
|
|
||||||
public SpriteAnimationGroup Add(SpriteAnimation anim, Func<bool> condition) {
|
public SpriteAnimationGroup Add(SpriteAnimation anim, Func<bool> condition, int priority = 0) {
|
||||||
this.animations.Add(new ConditionedAnimation(anim, condition));
|
this.animations.Add(new ConditionedAnimation(anim, condition, priority));
|
||||||
|
this.animations.Sort((a1, a2) => a1.Priority.CompareTo(a2.Priority));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(GameTime time) {
|
public void Update(GameTime time) {
|
||||||
if (this.currAnimation == null || !this.currAnimation.ShouldPlay()) {
|
ConditionedAnimation animToPlay = null;
|
||||||
this.currAnimation = null;
|
if (this.currAnimation != null && this.currAnimation.ShouldPlay())
|
||||||
|
animToPlay = this.currAnimation;
|
||||||
foreach (var anim in this.animations) {
|
foreach (var anim in this.animations) {
|
||||||
if (anim.ShouldPlay()) {
|
// if we find an animation with a lower priority then it means we can break
|
||||||
this.currAnimation = anim;
|
// because the list is sorted by priority
|
||||||
anim.Animation.Restart();
|
if (animToPlay != null && anim.Priority < animToPlay.Priority)
|
||||||
break;
|
break;
|
||||||
|
if (anim.ShouldPlay())
|
||||||
|
animToPlay = anim;
|
||||||
}
|
}
|
||||||
|
if (animToPlay != this.currAnimation) {
|
||||||
|
this.OnAnimationChanged?.Invoke(this.currAnimation?.Animation, animToPlay?.Animation);
|
||||||
|
this.currAnimation = animToPlay;
|
||||||
|
if (animToPlay != null)
|
||||||
|
animToPlay.Animation.Restart();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (this.currAnimation != null)
|
if (this.currAnimation != null)
|
||||||
this.currAnimation.Animation.Update(time);
|
this.currAnimation.Animation.Update(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SpriteAnimation ByName(string name) {
|
||||||
|
return this.animations.Find(anim => anim.Animation.Name == name)?.Animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void AnimationChanged(SpriteAnimation oldAnim, SpriteAnimation newAnim);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ConditionedAnimation {
|
internal class ConditionedAnimation {
|
||||||
|
|
||||||
public readonly SpriteAnimation Animation;
|
public readonly SpriteAnimation Animation;
|
||||||
public readonly Func<bool> ShouldPlay;
|
public readonly Func<bool> ShouldPlay;
|
||||||
|
public readonly int Priority;
|
||||||
|
|
||||||
public ConditionedAnimation(SpriteAnimation animation, Func<bool> shouldPlay) {
|
public ConditionedAnimation(SpriteAnimation animation, Func<bool> shouldPlay, int priority) {
|
||||||
this.Animation = animation;
|
this.Animation = animation;
|
||||||
this.ShouldPlay = shouldPlay;
|
this.ShouldPlay = shouldPlay;
|
||||||
|
this.Priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue