From e2624fe638ec0e1a77221598e6e0340e725e5f78 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Mon, 7 May 2012 18:23:03 -0500 Subject: [PATCH] Adding support for Glee2D --- axios.suo | Bin 205824 -> 223232 bytes axios/Axios_WP7.csproj | 1 + axios/Axios_Windows.csproj | 1 + axios/Axios_Xbox_360.csproj | 1 + axios/Axios_settings.cs | 1 + axios/Engine/Glee2D/Level.cs | 505 +++++++++++++++++++++++++++++++++++ 6 files changed, 509 insertions(+) create mode 100644 axios/Engine/Glee2D/Level.cs diff --git a/axios.suo b/axios.suo index ebbe51d11c343b9aac38acfda303ab88bdb3d697..d52e932a48459af9de0b7ecd37c1648d550ffc8e 100644 GIT binary patch delta 5620 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 W)4ch5-(SapXB=$P$%3zG*1rMr-DCOy delta 2411 zcmc&#X>3zR5Pq}o#r6wM;+#zhIEF$`i-s|RAm}*Zs4bAL1|vsC(34Uh z)op5wFcforYZPow&?NZ znca*$#`CmWSIFv})R~g${Da0??`W{B9v4Y$*|+40num2L}>fux4yxtg|5mjkRNjHktV6X zW~Yb|+GdveG-sJ!taJcfYHyGsmFoznP!p&-&q>Dqvw&cpMds-VL-UIZGUzBrFZ3@Z z(R7^BQSO*C@OD$eIq3b8nl>ttx_Zm0eHl76piGQr=k0JrPorH{Ry7n3>(slGa}t?v zKe6l8!p{$jbmPK&>YHI=caM@5qMEr1#_5v3pinq(4ws4wlEf$ZMQVaMEt*4^B5Z z-QuK;C0&0gH&$b=aK)47%9b@#QmD-qjd`2EtWGQp=w7XdO~@qSg3z8KTD1!@sw0*i zB>%EB&l2#+=$}UBVcDldhZ}~9Cj4+QsYg#dn9#Be&SSF#26SE~$+&R>*-hSmV*I>~au}vu_`ZZH(s)@9}v=o?9L00Pj^9qnRr#~xiAa)a0 z#X+U_M=~9oWujvfM~mxYyp>QWIrxQ!MvS>D!6?(XacLNs3ekA528P$JhLc2wVce#m z-7Z)KMxvi8%;%bZxTh8tGY^FVqG1FEzlP!1b%0nd3PN{0?u8SaDWS{VBhj*(#9?F| zOz>`iNwHU>RMXD6tLm!qjx@isyH!e{oBG7#_$D%_b}bZu41;+1A>l(Kv;nEW#p|F* z4!!xp@D2;E1EWYwiX5!60R{qkz5zdayr7`P0qLmx#e3sNP--`U0}N*F_eQ&~d$Z>I zV44FRH88MtE3dY#itR8m#JG3BNEx)ZT@-eLAbYq2iiz}ISi{`A!DW!5!!iaBaxX#8 z<@k1;`+GRcwq6F09{oo_p)Dn5R(TA{MQS={L)&S{+4=)Wyj{=$t?(jurd)&~Kwm8^ z#QY0nCm*piG~Xd6nz=93P^L7I0|d*gAW1_Cik)clK(*H8Kjlba1jk*Yuoka9fr)4h zfD!$7!G?Ppp$5BNg;VJCLoTiA>tNR}fmz1NPQX|p;XfB_*ZT>S`) z?B;Dqk + 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); + } + } + + + } +}