From 200058a61160bf3ec305bf871c97dd4431fcab57 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sun, 7 Mar 2021 22:03:29 +0100 Subject: [PATCH] added a method to make sidescrolling collision detection easier with TiledMapCollisions --- MLEM.Extended/Extensions/NumberExtensions.cs | 7 ++++++ MLEM.Extended/Tiled/TiledMapCollisions.cs | 26 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/MLEM.Extended/Extensions/NumberExtensions.cs b/MLEM.Extended/Extensions/NumberExtensions.cs index 94d4fb2..b85f9a4 100644 --- a/MLEM.Extended/Extensions/NumberExtensions.cs +++ b/MLEM.Extended/Extensions/NumberExtensions.cs @@ -1,3 +1,5 @@ +using Microsoft.Xna.Framework; +using MLEM.Extensions; using MonoGame.Extended; namespace MLEM.Extended.Extensions { @@ -24,5 +26,10 @@ namespace MLEM.Extended.Extensions { return new Misc.RectangleF(rect.X, rect.Y, rect.Width, rect.Height); } + /// + public static bool Penetrate(this RectangleF rect, RectangleF other, out Vector2 normal, out float penetration) { + return rect.ToMlem().Penetrate(other.ToMlem(), out normal, out penetration); + } + } } \ No newline at end of file diff --git a/MLEM.Extended/Tiled/TiledMapCollisions.cs b/MLEM.Extended/Tiled/TiledMapCollisions.cs index 563ddf7..91cad36 100644 --- a/MLEM.Extended/Tiled/TiledMapCollisions.cs +++ b/MLEM.Extended/Tiled/TiledMapCollisions.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; +using MLEM.Extended.Extensions; using MLEM.Extensions; using MLEM.Misc; using MonoGame.Extended.Tiled; @@ -110,6 +111,31 @@ namespace MLEM.Extended.Tiled { return this.GetCollidingTiles(area, included).Any(); } + /// + /// Returns a set of normals and penetration amounts for each that intersects with the given area. + /// The normals and penetration amounts are based on . + /// Note that all x penetrations are returned before all y penetrations, which improves collision detection in sidescrolling games with gravity. + /// + /// The area to penetrate + /// A set of normals and penetration amounts + public IEnumerable<(Vector2, float)> GetPenetrations(Func getArea) { + foreach (var col in this.GetCollidingAreas(getArea())) { + if (getArea().Penetrate(col, out var normal, out var penetration) && normal.X != 0) + yield return (normal, penetration); + } + foreach (var col in this.GetCollidingAreas(getArea())) { + if (getArea().Penetrate(col, out var normal, out var penetration) && normal.Y != 0) + yield return (normal, penetration); + } + } + + private IEnumerable GetCollidingAreas(RectangleF area, Func included = null) { + foreach (var tile in this.GetCollidingTiles(area, included)) { + foreach (var col in tile.Collisions) + yield return col; + } + } + /// /// A delegate method used to override the default collision checking behavior. ///