Last active
January 22, 2022 16:51
-
-
Save ZachIsAGardner/77fc60884504408dd789f5f09c1cfbb6 to your computer and use it in GitHub Desktop.
Animator Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using Microsoft.Xna.Framework.Audio; | |
namespace MyMonoGame | |
{ | |
public class AnimationState | |
{ | |
public string Name; | |
public int Start; | |
public int End; | |
public bool Loop = true; | |
public float Speed = 10; | |
public List<AnimationEvent> Events; | |
public bool Reverse; | |
public AnimationState(string name, int start, int? end = null, bool loop = true, float speed = 10, List<AnimationEvent> events = null) | |
{ | |
Name = name; | |
Start = start; | |
End = end ?? start; | |
Loop = loop; | |
Speed = speed; | |
Events = events; | |
if (end < start) | |
{ | |
Reverse = true; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace MyMonoGame | |
{ | |
public class Animator : Component | |
{ | |
// Public | |
public AnimationState State; | |
public int Offset = 0; | |
public float Frame = 1; | |
// Private | |
Sprite sprite; | |
int min = 1; | |
int max; | |
float speed = 10; | |
AnimationState oldState; | |
int? oldFrame; | |
// Methods | |
public void SetState(AnimationState state) | |
{ | |
sprite = sprite ?? Entity.GetComponent<Sprite>(); | |
if (state?.Name != oldState?.Name) | |
{ | |
Frame = state.Start; | |
int flooredFrame = (int)Math.Floor(Frame); | |
sprite.TileNumber = flooredFrame + Offset; | |
} | |
speed = state.Speed; | |
State = state; | |
} | |
public override void Setup() | |
{ | |
base.Setup(); | |
sprite = Entity.GetComponent<Sprite>(); | |
// Calculate maximum Frame based on our Sprite's spritesheet | |
max = (int)MathF.Floor( | |
(sprite.Texture.Width / sprite.TileSize.Value) | |
* (sprite.Texture.Height / sprite.TileSize.Value) | |
); | |
} | |
public override void Start() | |
{ | |
base.Start(); | |
} | |
public override void Update() | |
{ | |
base.Update(); | |
if (State == null) return; | |
// Check if State is different | |
if (State?.Name != oldState?.Name) | |
{ | |
Frame = State.Start; | |
} | |
speed = State.Speed; | |
// Increment Frame | |
Frame += (speed * Time.Delta) * (State.Reverse ? -1 : 1); | |
// Check if we've passed the end of the spritesheet. | |
if (Frame >= max + min) Frame = State.Loop ? State.Start : max; | |
// Loop | |
if (State.Reverse) | |
{ | |
if (Frame <= State.End) Frame = State.Loop ? State.Start : State.End; | |
} | |
else | |
{ | |
if (Frame >= State.End + 1) Frame = State.Loop ? State.Start : State.End; | |
} | |
// Update our Sprite component | |
int flooredFrame = (int)Math.Floor(Frame); | |
sprite.TileNumber = flooredFrame + Offset; | |
// Process events | |
if (flooredFrame != oldFrame && State.Events != null && State.Events.Count > 0) | |
{ | |
AnimationEvent animationEvent = State.Events.Find(e => e.Frames.Contains(flooredFrame)); | |
if (animationEvent != null) | |
{ | |
animationEvent.Action(); | |
} | |
} | |
// Remember stuff | |
oldFrame = flooredFrame; | |
oldState = State; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment