diff --git a/axios.suo b/axios.suo index ebbe51d..d52e932 100644 Binary files a/axios.suo and b/axios.suo differ diff --git a/axios/Axios_WP7.csproj b/axios/Axios_WP7.csproj index 1eb439b..c08a9d5 100644 --- a/axios/Axios_WP7.csproj +++ b/axios/Axios_WP7.csproj @@ -172,6 +172,7 @@ + diff --git a/axios/Axios_Windows.csproj b/axios/Axios_Windows.csproj index a6d6a15..e97654d 100644 --- a/axios/Axios_Windows.csproj +++ b/axios/Axios_Windows.csproj @@ -215,6 +215,7 @@ + diff --git a/axios/Axios_Xbox_360.csproj b/axios/Axios_Xbox_360.csproj index 29027e3..a982dc3 100644 --- a/axios/Axios_Xbox_360.csproj +++ b/axios/Axios_Xbox_360.csproj @@ -165,6 +165,7 @@ + diff --git a/axios/Axios_settings.cs b/axios/Axios_settings.cs index 381763e..d54ed88 100644 --- a/axios/Axios_settings.cs +++ b/axios/Axios_settings.cs @@ -69,6 +69,7 @@ * - Adding SplitFlat extension for Texture2D * - Removing uneeded Game Screen checking code * - Adding SplitFlat extension with offsets for Texture2D + * - Adding support for Glee2D * */ diff --git a/axios/Engine/Glee2D/Level.cs b/axios/Engine/Glee2D/Level.cs new file mode 100644 index 0000000..eba32c8 --- /dev/null +++ b/axios/Engine/Glee2D/Level.cs @@ -0,0 +1,505 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Content; +using System.IO; +using FarseerPhysics.Dynamics; +using FarseerPhysics.Common; +using FarseerPhysics.SamplesFramework; +using FarseerPhysics.Factories; + +namespace Axios.Engine.Glee2D +{ + public partial class Level + { + private World _world; + + /// + /// The name of the level. + /// + [XmlAttribute()] + public String Name; + + [XmlAttribute()] + public bool Visible; + + /// + /// A Level contains several Layers. Each Layer contains several Items. + /// + public List Layers; + + /// + /// A Dictionary containing any user-defined Properties. + /// + public SerializableDictionary CustomProperties; + + + public Level() + { + Visible = true; + Layers = new List(); + CustomProperties = new SerializableDictionary(); + } + + public Level(World world) + { + Visible = true; + Layers = new List(); + CustomProperties = new SerializableDictionary(); + _world = world; + } + + public static Level FromFile(string filename, ContentManager cm, World world) + { + FileStream stream = System.IO.File.Open(filename, FileMode.Open); + XmlSerializer serializer = new XmlSerializer(typeof(Level)); + Level level = (Level)serializer.Deserialize(stream); + stream.Close(); + + foreach (Layer layer in level.Layers) + { + foreach (Item item in layer.Items) + { + item.CustomProperties.RestoreItemAssociations(level); + item.load(cm, world); + } + } + + return level; + } + + public Item getItemByName(string name) + { + foreach (Layer layer in Layers) + { + foreach (Item item in layer.Items) + { + if (item.Name == name) return item; + } + } + return null; + } + + public Layer getLayerByName(string name) + { + foreach (Layer layer in Layers) + { + if (layer.Name == name) return layer; + } + return null; + } + + public void draw(SpriteBatch sb) + { + foreach (Layer layer in Layers) layer.draw(sb); + } + + + } + + + public partial class Layer + { + /// + /// The name of the layer. + /// + [XmlAttribute()] + public String Name; + + /// + /// Should this layer be visible? + /// + [XmlAttribute()] + public bool Visible; + + /// + /// The list of the items in this layer. + /// + public List Items; + + /// + /// The Scroll Speed relative to the main camera. The X and Y components are + /// interpreted as factors, so (1;1) means the same scrolling speed as the main camera. + /// Enables parallax scrolling. + /// + public Vector2 ScrollSpeed; + + + public Layer() + { + Items = new List(); + ScrollSpeed = Vector2.One; + } + + public void draw(SpriteBatch sb) + { + if (!Visible) return; + foreach (Item item in Items) item.draw(sb); + } + + } + + + [XmlInclude(typeof(TextureItem))] + [XmlInclude(typeof(RectangleItem))] + [XmlInclude(typeof(CircleItem))] + [XmlInclude(typeof(PathItem))] + public partial class Item + { + /// + /// The name of this item. + /// + [XmlAttribute()] + public String Name; + + /// + /// Should this item be visible? + /// + [XmlAttribute()] + public bool Visible; + + /// + /// The item's position in world space. + /// + public Vector2 Position; + + /// + /// A Dictionary containing any user-defined Properties. + /// + public SerializableDictionary CustomProperties; + + + public Item() + { + CustomProperties = new SerializableDictionary(); + } + + /// + /// Called by Level.FromFile(filename) on each Item after the deserialization process. + /// Should be overriden and can be used to load anything needed by the Item (e.g. a texture). + /// + public virtual void load(ContentManager cm, World world) + { + } + + public virtual void draw(SpriteBatch sb) + { + } + } + + + public partial class TextureItem : Item + { + /// + /// The item's rotation in radians. + /// + public float Rotation; + + /// + /// The item's scale factor. + /// + public float Scale; + + /// + /// The color to tint the item's texture with (use white for no tint). + /// + public Color TintColor; + + /// + /// If true, the texture is flipped horizontally when drawn. + /// + public bool FlipHorizontally; + + /// + /// If true, the texture is flipped vertically when drawn. + /// + public bool FlipVertically; + + /// + /// The path to the texture's filename (including the extension) relative to ContentRootFolder. + /// + public String texture_filename; + + /// + /// The texture_filename without extension. For using in Content.Load(). + /// + public String asset_name; + + /// + /// The XNA texture to be drawn. Can be loaded either from file (using "texture_filename") + /// or via the Content Pipeline (using "asset_name") - then you must ensure that the texture + /// exists as an asset in your project. + /// Loading is done in the Item's load() method. + /// + Texture2D texture; + + /// + /// The item's origin relative to the upper left corner of the texture. Usually the middle of the texture. + /// Used for placing and rotating the texture when drawn. + /// + public Vector2 Origin; + + + public TextureItem() + { + } + + /// + /// Called by Level.FromFile(filename) on each Item after the deserialization process. + /// Loads all assets needed by the TextureItem, especially the Texture2D. + /// You must provide your own implementation. However, you can rely on all public fields being + /// filled by the level deserialization process. + /// + public override void load(ContentManager cm, World world) + { + //throw new NotImplementedException(); + + //TODO: provide your own implementation of how a TextureItem loads its assets + //for example: + //this.texture = Texture2D.FromFile(, texture_filename); + //or by using the Content Pipeline: + this.texture = cm.Load(asset_name); + + } + + public override void draw(SpriteBatch sb) + { + if (!Visible) return; + SpriteEffects effects = SpriteEffects.None; + if (FlipHorizontally) effects |= SpriteEffects.FlipHorizontally; + if (FlipVertically) effects |= SpriteEffects.FlipVertically; + sb.Draw(texture, Position, null, TintColor, Rotation, Origin, Scale, effects, 0); + } + } + + + public partial class RectangleItem : Item + { + public float Width; + public float Height; + public Color FillColor; + + Body _body; + + public RectangleItem() + { + } + + public override void load(ContentManager cm, World world) + { + base.load(cm, world); + + _body = BodyFactory.CreateRectangle(world, Width, Height, 1f); + _body.Position = Position; + _body.UserData = this; + } + } + + + public partial class CircleItem : Item + { + public float Radius; + public Color FillColor; + + Body _body; + + public CircleItem() + { + } + + public override void load(ContentManager cm, World world) + { + base.load(cm, world); + + _body = BodyFactory.CreateCircle(world, Radius, 1f); + _body.Position = Position; + _body.UserData = this; + } + + } + + + public partial class PathItem : Item + { + public Vector2[] LocalPoints; + public Vector2[] WorldPoints; + public bool IsPolygon; + public int LineWidth; + public Color LineColor; + + Body _body; + + public PathItem() + { + } + + public override void load(ContentManager cm, World world) + { + base.load(cm, world); + + Vertices v = new Vertices(WorldPoints.Length); + foreach (Vector2 vec in WorldPoints) + v.Add(new Vector2(ConvertUnits.ToSimUnits(vec.X), ConvertUnits.ToSimUnits(vec.Y))); + + _body = BodyFactory.CreateLoopShape(world, v); + _body.Position = this.Position; + _body.UserData = this; + } + + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + // + // NEEDED FOR SERIALIZATION. YOU SHOULDN'T CHANGE ANYTHING BELOW! + // + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + + public class CustomProperty + { + public string name; + public object value; + public Type type; + public string description; + + public CustomProperty() + { + } + + public CustomProperty(string n, object v, Type t, string d) + { + name = n; + value = v; + type = t; + description = d; + } + + public CustomProperty clone() + { + CustomProperty result = new CustomProperty(name, value, type, description); + return result; + } + } + + + public class SerializableDictionary : Dictionary, IXmlSerializable + { + + public SerializableDictionary() + : base() + { + + } + + public SerializableDictionary(SerializableDictionary copyfrom) + : base(copyfrom) + { + string[] keyscopy = new string[Keys.Count]; + Keys.CopyTo(keyscopy, 0); + foreach (string key in keyscopy) + { + this[key] = this[key].clone(); + } + } + + public System.Xml.Schema.XmlSchema GetSchema() + { + return null; + } + + public void ReadXml(System.Xml.XmlReader reader) + { + + bool wasEmpty = reader.IsEmptyElement; + reader.Read(); + + if (wasEmpty) return; + + while (reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + CustomProperty cp = new CustomProperty(); + cp.name = reader.GetAttribute("Name"); + cp.description = reader.GetAttribute("Description"); + + string type = reader.GetAttribute("Type"); + if (type == "string") cp.type = typeof(string); + if (type == "bool") cp.type = typeof(bool); + if (type == "Vector2") cp.type = typeof(Vector2); + if (type == "Color") cp.type = typeof(Color); + if (type == "Item") cp.type = typeof(Item); + + if (cp.type == typeof(Item)) + { + cp.value = reader.ReadInnerXml(); + this.Add(cp.name, cp); + } + else + { + reader.ReadStartElement("Property"); + XmlSerializer valueSerializer = new XmlSerializer(cp.type); + object obj = valueSerializer.Deserialize(reader); +#if WINDOWS + cp.value = Convert.ChangeType(obj, cp.type); +#elif WINDOWS_PHONE || XBOX360 + cp.value = Convert.ChangeType(obj, cp.type, null); +#endif + this.Add(cp.name, cp); + reader.ReadEndElement(); + } + + reader.MoveToContent(); + } + reader.ReadEndElement(); + } + + public void WriteXml(System.Xml.XmlWriter writer) + { + foreach (String key in this.Keys) + { + writer.WriteStartElement("Property"); + writer.WriteAttributeString("Name", this[key].name); + if (this[key].type == typeof(string)) writer.WriteAttributeString("Type", "string"); + if (this[key].type == typeof(bool)) writer.WriteAttributeString("Type", "bool"); + if (this[key].type == typeof(Vector2)) writer.WriteAttributeString("Type", "Vector2"); + if (this[key].type == typeof(Color)) writer.WriteAttributeString("Type", "Color"); + if (this[key].type == typeof(Item)) writer.WriteAttributeString("Type", "Item"); + writer.WriteAttributeString("Description", this[key].description); + + if (this[key].type == typeof(Item)) + { + Item item = (Item)this[key].value; + if (item != null) writer.WriteString(item.Name); + else writer.WriteString("$null$"); + } + else + { + XmlSerializer valueSerializer = new XmlSerializer(this[key].type); + valueSerializer.Serialize(writer, this[key].value); + } + writer.WriteEndElement(); + } + } + + /// + /// Must be called after all Items have been deserialized. + /// Restores the Item references in CustomProperties of type Item. + /// + public void RestoreItemAssociations(Level level) + { + foreach (CustomProperty cp in Values) + { + if (cp.type == typeof(Item)) cp.value = level.getItemByName((string)cp.value); + } + } + + + } +}