1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-05-20 08:01:21 +02:00

added a method to make sidescrolling collision detection easier with TiledMapCollisions

This commit is contained in:
Ell 2021-03-07 22:03:29 +01:00
parent 6ef9f8ffb1
commit 200058a611
2 changed files with 33 additions and 0 deletions

View file

@ -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);
}
/// <inheritdoc cref="MLEM.Extensions.NumberExtensions.Penetrate"/>
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);
}
}
}

View file

@ -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();
}
/// <summary>
/// Returns a set of normals and penetration amounts for each <see cref="TileCollisionInfo"/> that intersects with the given <see cref="RectangleF"/> area.
/// The normals and penetration amounts are based on <see cref="MLEM.Extensions.NumberExtensions.Penetrate"/>.
/// Note that all x penetrations are returned before all y penetrations, which improves collision detection in sidescrolling games with gravity.
/// </summary>
/// <param name="getArea">The area to penetrate</param>
/// <returns>A set of normals and penetration amounts</returns>
public IEnumerable<(Vector2, float)> GetPenetrations(Func<RectangleF> 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<RectangleF> GetCollidingAreas(RectangleF area, Func<TileCollisionInfo, bool> included = null) {
foreach (var tile in this.GetCollidingTiles(area, included)) {
foreach (var col in tile.Collisions)
yield return col;
}
}
/// <summary>
/// A delegate method used to override the default collision checking behavior.
/// </summary>