Skip to content

Instantly share code, notes, and snippets.

@tcsavage
Created April 27, 2011 17:21
Show Gist options
  • Save tcsavage/944728 to your computer and use it in GitHub Desktop.
Save tcsavage/944728 to your computer and use it in GitHub Desktop.
Keyframe animation helper class
using System.Collections.Generic;
using Microsoft.Xna.Framework;
namespace PuzzleGame
{
/// <summary>
/// Keyframe animation helper class.
/// </summary>
public class Animation
{
/// <summary>
/// List of keyframes in the animation.
/// </summary>
List<Keyframe> keyframes = new List<Keyframe>();
/// <summary>
/// Current position in the animation.
/// </summary>
int timeline;
/// <summary>
/// The last frame of the animation (set when keyframes are added).
/// </summary>
int lastFrame = 0;
/// <summary>
/// Marks the animation as ready to run/running.
/// </summary>
bool run = false;
/// <summary>
/// Current keyframe index.
/// </summary>
int currentIndex;
/// <summary>
/// Construct new animation helper.
/// </summary>
public Animation()
{
}
/// <summary>
/// Add a keyframe to the animation.
/// </summary>
/// <param name="time">Time for keyframe to happen.</param>
/// <param name="value">Value at keyframe.</param>
public void AddKeyframe(int time, float value)
{
Keyframe k = new Keyframe();
k.time = time;
k.value = value;
keyframes.Add(k);
keyframes.Sort(delegate(Keyframe a, Keyframe b) { return a.time.CompareTo(b.time); });
lastFrame = (time > lastFrame) ? time : lastFrame;
}
/// <summary>
/// Reset the animation and flag it as ready to run.
/// </summary>
public void Start()
{
timeline = 0;
currentIndex = 0;
run = true;
}
/// <summary>
/// Update the animation timeline.
/// </summary>
/// <param name="gameTime">Current game time.</param>
/// <param name="value">Reference to value to change.</param>
public void Update(GameTime gameTime, ref float value)
{
if (run)
{
timeline += gameTime.ElapsedGameTime.Milliseconds;
value = MathHelper.SmoothStep(keyframes[currentIndex].value, keyframes[currentIndex + 1].value, (float)timeline / (float)keyframes[currentIndex + 1].time);
if (timeline >= keyframes[currentIndex + 1].time && currentIndex != keyframes.Count) { currentIndex++; }
if (timeline >= lastFrame) { run = false; }
}
}
/// <summary>
/// Represents a keyframe on the timeline.
/// </summary>
public struct Keyframe
{
public int time;
public float value;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment