From ace089e9d8027d968dbe7c0bb4613f9412152ca6 Mon Sep 17 00:00:00 2001 From: KatDevsGames Date: Mon, 8 Apr 2024 18:22:41 -0500 Subject: [PATCH 1/2] tiled content pipeline bugfixes & new fields added support for reading type field & repeatX/repeatY from Tiled image layers (renderer still does not support this) property value read bugfix Til;edMapProperties.cs:10 --- .../Tiled/ContentWriterExtensions.cs | 2 ++ .../Tiled/TiledMapWriter.cs | 2 ++ .../ContentReaderExtensions.cs | 5 ++++- .../TiledMapImageLayerContent.cs | 8 ++++++++ .../Serialization/TiledMapPropertyContent.cs | 6 ++++++ .../TiledMapImageLayer.cs | 6 +++++- .../TiledMapProperties.cs | 2 +- .../TiledMapPropertyValue.cs | 20 +++++++------------ .../MonoGame.Extended.Tiled/TiledMapReader.cs | 8 +++++--- 9 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/ContentWriterExtensions.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/ContentWriterExtensions.cs index 28ded1733..60d3c3422 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/ContentWriterExtensions.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/ContentWriterExtensions.cs @@ -19,6 +19,8 @@ public static void WriteTiledMapProperties(this ContentWriter writer, IReadOnlyC { writer.Write(property.Name); writer.Write(property.Value ?? string.Empty); + writer.Write(property.Type ?? string.Empty); + writer.Write(property.PropertyType ?? string.Empty); WriteTiledMapProperties(writer, property.Properties); } } diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapWriter.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapWriter.cs index 126debbb3..ccbba8622 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapWriter.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapWriter.cs @@ -97,6 +97,8 @@ private void WriteLayer(ContentWriter writer, TiledMapLayerContent layer) switch (layer.LayerType) { case TiledMapLayerType.ImageLayer: + writer.Write(((TiledMapImageLayerContent)layer).RepeatX); + writer.Write(((TiledMapImageLayerContent)layer).RepeatY); WriteImageLayer(writer, (TiledMapImageLayerContent)layer); break; case TiledMapLayerType.TileLayer: diff --git a/src/cs/MonoGame.Extended.Tiled/ContentReaderExtensions.cs b/src/cs/MonoGame.Extended.Tiled/ContentReaderExtensions.cs index 86f1b6be9..6ce51c46a 100644 --- a/src/cs/MonoGame.Extended.Tiled/ContentReaderExtensions.cs +++ b/src/cs/MonoGame.Extended.Tiled/ContentReaderExtensions.cs @@ -11,7 +11,10 @@ public static void ReadTiledMapProperties(this ContentReader reader, TiledMapPro for (var i = 0; i < count; i++) { var key = reader.ReadString(); - var value = new TiledMapPropertyValue(reader.ReadString()); + var value = new TiledMapPropertyValue( + reader.ReadString(), + reader.ReadString(), + reader.ReadString()); ReadTiledMapProperties(reader, value.Properties); properties[key] = value; } diff --git a/src/cs/MonoGame.Extended.Tiled/Serialization/TiledMapImageLayerContent.cs b/src/cs/MonoGame.Extended.Tiled/Serialization/TiledMapImageLayerContent.cs index f347d1e70..9c4798ff2 100644 --- a/src/cs/MonoGame.Extended.Tiled/Serialization/TiledMapImageLayerContent.cs +++ b/src/cs/MonoGame.Extended.Tiled/Serialization/TiledMapImageLayerContent.cs @@ -14,10 +14,18 @@ public class TiledMapImageLayerContent : TiledMapLayerContent [XmlElement(ElementName = "image")] public TiledMapImageContent Image { get; set; } + [XmlAttribute(AttributeName = "repeatx")] + public bool RepeatX { get; set; } + + [XmlAttribute(AttributeName = "repeaty")] + public bool RepeatY { get; set; } + public TiledMapImageLayerContent() : base(TiledMapLayerType.ImageLayer) { Opacity = 1.0f; + RepeatX = false; + RepeatY = false; Visible = true; Properties = new List(); } diff --git a/src/cs/MonoGame.Extended.Tiled/Serialization/TiledMapPropertyContent.cs b/src/cs/MonoGame.Extended.Tiled/Serialization/TiledMapPropertyContent.cs index 10cdfc15c..f1251950f 100644 --- a/src/cs/MonoGame.Extended.Tiled/Serialization/TiledMapPropertyContent.cs +++ b/src/cs/MonoGame.Extended.Tiled/Serialization/TiledMapPropertyContent.cs @@ -11,6 +11,12 @@ public class TiledMapPropertyContent [XmlAttribute(AttributeName = "value")] public string ValueAttribute { get; set; } + [XmlAttribute(AttributeName = "type")] + public string Type { get; set; } + + [XmlAttribute(AttributeName = "propertytype")] + public string PropertyType { get; set; } + [XmlText] public string ValueBody { get; set; } diff --git a/src/cs/MonoGame.Extended.Tiled/TiledMapImageLayer.cs b/src/cs/MonoGame.Extended.Tiled/TiledMapImageLayer.cs index 33bb70083..b4f1f2afb 100644 --- a/src/cs/MonoGame.Extended.Tiled/TiledMapImageLayer.cs +++ b/src/cs/MonoGame.Extended.Tiled/TiledMapImageLayer.cs @@ -5,14 +5,18 @@ namespace MonoGame.Extended.Tiled { public class TiledMapImageLayer : TiledMapLayer, IMovable { - public TiledMapImageLayer(string name, string type, Texture2D image, Vector2? position = null, Vector2? offset = null, Vector2? parallaxFactor = null, float opacity = 1.0f, bool isVisible = true) + public TiledMapImageLayer(string name, string type, Texture2D image, Vector2? position = null, Vector2? offset = null, Vector2? parallaxFactor = null, float opacity = 1.0f, bool repeatX = false, bool repeatY = false, bool isVisible = true) : base(name, type, offset, parallaxFactor, opacity, isVisible) { Image = image; Position = position ?? Vector2.Zero; + RepeatX = repeatX; + RepeatY = repeatY; } public Texture2D Image { get; } public Vector2 Position { get; set; } + public bool RepeatX { get; set; } + public bool RepeatY { get; set; } } } diff --git a/src/cs/MonoGame.Extended.Tiled/TiledMapProperties.cs b/src/cs/MonoGame.Extended.Tiled/TiledMapProperties.cs index 651ae5dab..cc0949875 100644 --- a/src/cs/MonoGame.Extended.Tiled/TiledMapProperties.cs +++ b/src/cs/MonoGame.Extended.Tiled/TiledMapProperties.cs @@ -7,7 +7,7 @@ public class TiledMapProperties : Dictionary public bool TryGetValue(string key, out string value) { bool result = TryGetValue(key, out TiledMapPropertyValue tmpVal); - value = result ? null : tmpVal.Value; + value = result ? tmpVal.Value : null; return result; } } diff --git a/src/cs/MonoGame.Extended.Tiled/TiledMapPropertyValue.cs b/src/cs/MonoGame.Extended.Tiled/TiledMapPropertyValue.cs index d7a089318..034efb8da 100644 --- a/src/cs/MonoGame.Extended.Tiled/TiledMapPropertyValue.cs +++ b/src/cs/MonoGame.Extended.Tiled/TiledMapPropertyValue.cs @@ -4,26 +4,20 @@ public class TiledMapPropertyValue { public string Value { get; } - public TiledMapProperties Properties; + public string Type { get; } - public TiledMapPropertyValue() - { - Value = string.Empty; - Properties = new(); - } + public string PropertyType { get; } - public TiledMapPropertyValue(string value) + public TiledMapProperties Properties; + + public TiledMapPropertyValue(string value, string type, string propertyType) { Value = value; + Type = type; + PropertyType = propertyType; Properties = new(); } - public TiledMapPropertyValue(TiledMapProperties properties) - { - Value = string.Empty; - Properties = properties; - } - public override string ToString() => Value; //public static implicit operator TiledMapPropertyValue(string value) => new(value); diff --git a/src/cs/MonoGame.Extended.Tiled/TiledMapReader.cs b/src/cs/MonoGame.Extended.Tiled/TiledMapReader.cs index bd4965562..b45decff0 100644 --- a/src/cs/MonoGame.Extended.Tiled/TiledMapReader.cs +++ b/src/cs/MonoGame.Extended.Tiled/TiledMapReader.cs @@ -95,7 +95,9 @@ private static TiledMapLayer ReadLayer(ContentReader reader, TiledMap map) switch (layerType) { case TiledMapLayerType.ImageLayer: - layer = ReadImageLayer(reader, name, type, offset, parallaxFactor, opacity, isVisible); + var repeatX = reader.ReadBoolean(); + var repeatY = reader.ReadBoolean(); + layer = ReadImageLayer(reader, name, type, offset, parallaxFactor, opacity, repeatX, repeatY, isVisible); break; case TiledMapLayerType.TileLayer: layer = ReadTileLayer(reader, name, type, offset, parallaxFactor, opacity, isVisible, map); @@ -195,13 +197,13 @@ private static Point2[] ReadPoints(ContentReader reader) return points; } - private static TiledMapImageLayer ReadImageLayer(ContentReader reader, string name, string type, Vector2 offset, Vector2 parallaxFactor, float opacity, bool isVisible) + private static TiledMapImageLayer ReadImageLayer(ContentReader reader, string name, string type, Vector2 offset, Vector2 parallaxFactor, float opacity, bool repeatX, bool repeatY, bool isVisible) { var texture = reader.ReadExternalReference(); var x = reader.ReadSingle(); var y = reader.ReadSingle(); var position = new Vector2(x, y); - return new TiledMapImageLayer(name, type, texture, position, offset, parallaxFactor, opacity, isVisible); + return new TiledMapImageLayer(name, type, texture, position, offset, parallaxFactor, opacity, repeatX, repeatY, isVisible); } private static TiledMapTileLayer ReadTileLayer(ContentReader reader, string name, string type, Vector2 offset, Vector2 parallaxFactor, float opacity, bool isVisible, TiledMap map) From 6d1dc9dc51eb53c081e9ae53abb5c166b1f13db4 Mon Sep 17 00:00:00 2001 From: KatDevsGames Date: Mon, 8 Apr 2024 20:57:29 -0500 Subject: [PATCH 2/2] actor cast support for collision component this is a Cast function in CollisionComponent that ICollisionActor objects can use (not unlike the one that rigidbodies get in unity) --- .../CollisionComponent.cs | 45 +++++++++++++++++++ .../ISpaceAlgorithm.cs | 11 +++-- .../QuadTree/QuadTreeSpace.cs | 9 +++- .../SpatialHash.cs | 2 + 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/cs/MonoGame.Extended.Collisions/CollisionComponent.cs b/src/cs/MonoGame.Extended.Collisions/CollisionComponent.cs index 9677c14f8..a8e2ab0a2 100644 --- a/src/cs/MonoGame.Extended.Collisions/CollisionComponent.cs +++ b/src/cs/MonoGame.Extended.Collisions/CollisionComponent.cs @@ -6,6 +6,7 @@ using Microsoft.Xna.Framework; using MonoGame.Extended.Collisions.Layers; using MonoGame.Extended.Collisions.QuadTree; +using Newtonsoft.Json.Linq; namespace MonoGame.Extended.Collisions { @@ -97,6 +98,50 @@ public override void Update(GameTime gameTime) } } + /// + /// Cast an actor's colliders in a direction and check for collisions. + /// + /// The list of actor colliders to cast. + /// Normalized vector representing the direction to cast each shape. + /// Buffer to receive results. + /// Maximum distance over which to cast the Collider(s). + public int Cast(IEnumerable actors, Vector2 move, List hitBuffer, float distance) + { + hitBuffer.Clear(); + Vector2 offset = move.NormalizedCopy() * distance; + return Cast(actors, offset, hitBuffer); + } + + + /// + /// Cast an actor's colliders in a direction and check for collisions. + /// + /// The list of actor colliders to cast. + /// Vector representing the translation to use for each cast. + /// Buffer to receive results. + public int Cast(IEnumerable actors, Vector2 offset, List hitBuffer) + { + foreach (ICollisionActor actor in actors) + { + try + { + actor.Bounds.Position += offset; + foreach ((_, Layer secondLayer) in _layerCollision) + { + if (!secondLayer.Space.Contains(actor)) continue; + foreach (ICollisionActor other in secondLayer.Space.Query(actor.Bounds.BoundingRectangle)) + if (actor != other && actor.Bounds.Intersects(other.Bounds)) + { + CollisionEventArgs collisionInfo = new() { Other = other, PenetrationVector = CalculatePenetrationVector(actor.Bounds, other.Bounds) }; + hitBuffer.Add(collisionInfo); + } + } + } + finally { actor.Bounds.Position -= offset; } + } + return hitBuffer.Count; + } + /// /// Inserts the target into the collision tree. /// The target will have its OnCollision called when collisions occur. diff --git a/src/cs/MonoGame.Extended.Collisions/ISpaceAlgorithm.cs b/src/cs/MonoGame.Extended.Collisions/ISpaceAlgorithm.cs index a95f7379e..b1da46e17 100644 --- a/src/cs/MonoGame.Extended.Collisions/ISpaceAlgorithm.cs +++ b/src/cs/MonoGame.Extended.Collisions/ISpaceAlgorithm.cs @@ -21,10 +21,15 @@ public interface ISpaceAlgorithm bool Remove(ICollisionActor actor); /// - /// Removes the actor into the space. - /// The actor will have its OnCollision called when collisions occur. + /// Checks if an actor is within the space. /// - /// Actor to remove. + /// Actor to check for. + bool Contains(ICollisionActor actor); + + /// + /// Queries the space for collisions within a bounding rectangle. + /// + /// Rectangle to check against. IEnumerable Query(RectangleF boundsBoundingRectangle); /// diff --git a/src/cs/MonoGame.Extended.Collisions/QuadTree/QuadTreeSpace.cs b/src/cs/MonoGame.Extended.Collisions/QuadTree/QuadTreeSpace.cs index 3e9625f06..22ae0a6ee 100644 --- a/src/cs/MonoGame.Extended.Collisions/QuadTree/QuadTreeSpace.cs +++ b/src/cs/MonoGame.Extended.Collisions/QuadTree/QuadTreeSpace.cs @@ -49,8 +49,15 @@ public bool Remove(ICollisionActor target) return false; } + + /// + /// Checks if the target is within the space. + /// + /// Target to check for. + public bool Contains(ICollisionActor target) => _actors.Contains(target); + /// - /// Restructure a inner collection, if layer is dynamic, because actors can change own position + /// Restructure an inner collection, if layer is dynamic, because actors can change own position /// public void Reset() { diff --git a/src/cs/MonoGame.Extended.Collisions/SpatialHash.cs b/src/cs/MonoGame.Extended.Collisions/SpatialHash.cs index 2b0920e7d..2ab9e62d2 100644 --- a/src/cs/MonoGame.Extended.Collisions/SpatialHash.cs +++ b/src/cs/MonoGame.Extended.Collisions/SpatialHash.cs @@ -16,6 +16,8 @@ public SpatialHash(Size2 size) _size = size; } + public bool Contains(ICollisionActor actor) => _actors.Contains(actor); + public void Insert(ICollisionActor actor) { InsertToHash(actor);