The other day whilst experimenting with some projects I started looking round the web to see if there was a tool I could use to extract a Spritesheet I could use in XNA from an image which had number of different animation frames.
Well I couldnt find anything that exactly did what I wanted but I did find a little app called SpriteVortex.
This app seems to be able to scan an image and pick out the frames of your image using a colour key and construct a list of sprites. The app then lets you construct a list of animation sets which you can add each sprite too and it even has a little animation preview window where you can offset each frame to get them to animate correctly and set the animation time for each frame.
When you have done with your animation you can then export the whole thing to an XML file.
This all sounded good however I couldnt seem to find a way use this XML to generate animation in my own XNA project. So I got to thinking how I would do it. Well as the XML is simply XML I thought I might be able to write my own XML deserializer to read in the XML and construct the sprite and animation objects from the data.
After doing a bit of reading round on serializing and deserializing I came up with this cs file :-
namespace SpriteVortexDeserialize { [XmlRoot("Sprite")] public class Sprite { [XmlAttribute("Name")] public string Name; [XmlAttribute("Id")] public int Id; [XmlElement("Coordinates")] public Coordinates Coordinates; } [XmlRoot("Coordinates")] public class Coordinates { [XmlElement("X")] public int X; [XmlElement("Y")] public int Y; [XmlElement("Width")] public int Width; [XmlElement("Height")] public int Height; } [XmlRoot("Animation")] public class Animation { [XmlAttribute("Name")] public string Name; [XmlAttribute("FrameRate")] public int FrameRate; [XmlAttribute("Loop")] public string Loop; [XmlAttribute("PingPong")] public string PingPong; [XmlArray("Frames")] [XmlArrayItem("Frame", typeof(Frame))] public List<Frame> _frames; } [XmlRoot("Frame")] public class Frame { [XmlAttribute("SpriteId")] public int SpriteId; [XmlAttribute("OriginX")] public float OriginX; [XmlAttribute("OriginY")] public float OriginY; [XmlAttribute("OffSetX")] public int OffSetX; [XmlAttribute("OffSetY")] public int OffSetY; [XmlAttribute("Duration")] public float Duration; } [XmlRoot("Texture")] public class Texture { [XmlAttribute("Path")] public string Path; [XmlAttribute("Name")] public string Name; } [XmlRoot("SpriteMapping")] public class SpriteMapping { [XmlElement("Texture")] public Texture texture; [XmlArray("Sprites")] [XmlArrayItem("Sprite", typeof(Sprite))] public List<Sprite> _sprites; [XmlArray("Animations")] [XmlArrayItem("Animation", typeof(Animation))] public List<Animation> _animations; } }
Once you have this class you can then deserialize the XML into this object structure using this code :-
SpriteMapping spriteMapping = new SpriteMapping();
XmlSerializer serializer = new XmlSerializer(spriteMapping.GetType()); TextReader textReader = new StreamReader("./Content/testknight.xml"); spriteMapping = (SpriteMapping)serializer.Deserialize(textReader); textReader.Close();
As usual you would have to put your image assets and your XML into the Content project however you have to set the XML file to ContextProcessor = "No Processing Required" and Copy to Output Directory = "Always Copy".
Hope this helps somebody out who wants to use this little app without writing your own sprite manager functionality, also if I get some feedback on this post I might also upload a sample project but havent decided that yet.
Jase