Skip to content

Instantly share code, notes, and snippets.

@ZachIsAGardner
Last active January 22, 2022 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZachIsAGardner/77fc60884504408dd789f5f09c1cfbb6 to your computer and use it in GitHub Desktop.
Save ZachIsAGardner/77fc60884504408dd789f5f09c1cfbb6 to your computer and use it in GitHub Desktop.
Animator Example
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;
}
}
}
}
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