using System.Collections.Generic; using System.IO; using System.Xml; namespace Otter { /// /// Class used for loading textures from an Atlas, or a set of Atlases. This class is built to support /// atlases created with Sparrow/Starling exporting from TexturePacker http://www.codeandweb.com/texturepacker /// public class Atlas { #region Static Fields static Dictionary textures = new Dictionary(); #endregion #region Private Fields Dictionary subtextures = new Dictionary(); #endregion #region Constructors /// /// Designed for Sparrow/Starling exporting from TexturePacker http://www.codeandweb.com/texturepacker /// /// The reltive path to the atlas data file. The png should also be in the same directory. public Atlas(string source = "") { if (source != "") { Add(source); } } #endregion #region Indexers /// /// Get an AtlasTexture by name. /// /// The name of the image in the atlas data. /// An AtlasTexture. public AtlasTexture this[string name] { get { return GetTexture(name); } } #endregion #region Public Methods /// /// Add another atlas to the collection of textures. Duplicate names will destroy this. /// /// The relative path to the data file. The png should be in the same directory. public Atlas Add(string source) { var xml = new XmlDocument(); xml.Load(source); var atlas = xml.GetElementsByTagName("TextureAtlas"); var imagePath = Path.GetDirectoryName(source) + "/"; if (imagePath == "/") imagePath = ""; foreach (XmlElement a in xml.GetElementsByTagName("TextureAtlas")) { foreach (XmlElement e in xml.GetElementsByTagName("SubTexture")) { var name = e.AttributeString("name"); var uniqueName = true; foreach (var atest in subtextures.Values) { if (atest.Name == name) { uniqueName = false; break; } } if (uniqueName) { var atext = new AtlasTexture(); atext.X = e.AttributeInt("x"); atext.Y = e.AttributeInt("y"); atext.Width = e.AttributeInt("width"); atext.Height = e.AttributeInt("height"); atext.FrameHeight = e.AttributeInt("frameHeight", atext.Height); atext.FrameWidth = e.AttributeInt("frameWidth", atext.Width); atext.FrameX = e.AttributeInt("frameX", 0); atext.FrameY = e.AttributeInt("frameY", 0); atext.Name = name; atext.Source = imagePath + a.AttributeString("imagePath"); atext.Texture = new Texture(atext.Source); subtextures.Add(e.AttributeString("name"), atext); } } } return this; } /// /// Add multiple sources to the Atlas. /// /// The file path to the sources. /// The Atlas. public Atlas AddMultiple(params string[] sources) { foreach (string s in sources) { Add(s); } return this; } /// /// Add multiple atlases from a set created by texture packer. /// Note: This only supports up to 10 atlases (0 - 9) /// /// The path until the number. For example: "assets/atlas" if the path is "assets/atlas0.xml" /// The extension of the source without a dot /// The Atlas. public Atlas AddNumbered(string source, string extension = "xml") { var i = 0; while (File.Exists(source + i + "." + extension)) { Add(source + i + "." + extension); i++; } return this; } /// /// Creates a new Image from an AtlasTexture. /// /// The name of the texture in the atlas data. /// The created Image. public Image CreateImage(string name) { return new Image(this[name]); } /// /// Creates a new Spritemap from an AtlasTexture. /// /// The type to use to reference animations. /// The name of the texture in the atlas data. /// The width of the cell on the sprite sheet. /// The height of the cell on the sprite sheet. /// The new Spritemap. public Spritemap CreateSpritemap(string name, int width, int height) { return new Spritemap(this[name], width, height); } /// /// Get an AtlasTexture by name. /// /// The name of the image in the atlas data. /// An AtlasTexture. public AtlasTexture GetAtlasTexture(string name) { return GetTexture(name); } /// /// Tests if a texture by the specified name exists in the atlas data. /// /// The name of the texture to test. /// True if the atlas data contains a texture by the specified name. public bool Exists(string name) { return subtextures.ContainsKey(name); } #endregion #region Internal internal AtlasTexture GetTexture(string name) { var a = subtextures[name]; return a; } #endregion } /// /// Class used for representing a texture on a texture atlas. /// public class AtlasTexture { #region Public Fields /// /// The X position of the texture in the atlas. /// public int X; /// /// The Y position of the texture in the atlas. /// public int Y; /// /// The width of the texture in the atlas. /// public int Width; /// /// The height of the texture in the atlas. /// public int Height; /// /// The frame width of the texture in the atlas (used in Trim mode.) /// Trim is not supported yet. /// public int FrameWidth; /// /// The frame height of the texture in the atlas (used in Trim mode.) /// Trim is not supported yet. /// public int FrameHeight; /// /// The frame X position of the texture in the atlas (used in Trim mode.) /// Trim is not supported yet. /// public int FrameX; /// /// The frame Y position of the texture in the atlas (used in Trim mode.) /// Trim is not supported yet. /// public int FrameY; /// /// The name of the texture in the atlas. /// public string Name; /// /// The file path source of the texture. /// public string Source; /// /// The texture loaded for this atlas texture. /// public Texture Texture; #endregion #region Public Properties /// /// The rectangle region of the texture in the atlas. /// public Rectangle Region { get { return new Rectangle(X, Y, Width, Height); } } #endregion #region Public Methods public override string ToString() { return Name + " " + Source + " X: " + X + " Y: " + Y + " Width: " + Width + " Height: " + Height + " FrameX: " + FrameX + " FrameY: " + FrameY + " FrameWidth: " + FrameWidth + " FrameHeight: " + FrameHeight; } #endregion } }