1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-03 22:03:37 +02:00

added Direction2Helper.RotateBy

This commit is contained in:
Ell 2021-07-05 19:46:39 +02:00
parent d1b229b589
commit f352e6b437
3 changed files with 74 additions and 46 deletions

View file

@ -7,11 +7,15 @@ Jump to version:
## 5.1.0 (Unreleased) ## 5.1.0 (Unreleased)
### MLEM ### MLEM
Additions
- Added RotateBy to Direction2Helper
Fixes Fixes
- Set default values for InputHandler held and pressed keys to avoid an exception if buttons are held in the very first frame - Set default values for InputHandler held and pressed keys to avoid an exception if buttons are held in the very first frame
Improvements Improvements
- Improved NinePatch memory performance - Improved NinePatch memory performance
- Moved sound-related classes into Sound namespace
### MLEM.Ui ### MLEM.Ui
Fixes Fixes

View file

@ -85,6 +85,9 @@ namespace MLEM.Misc {
/// </summary> /// </summary>
public static readonly Direction2[] AllExceptNone = All.Where(dir => dir != Direction2.None).ToArray(); public static readonly Direction2[] AllExceptNone = All.Where(dir => dir != Direction2.None).ToArray();
private static readonly Direction2[] Clockwise = {Direction2.Up, Direction2.UpRight, Direction2.Right, Direction2.DownRight, Direction2.Down, Direction2.DownLeft, Direction2.Left, Direction2.UpLeft};
private static readonly Dictionary<Direction2, int> ClockwiseLookup = Clockwise.Select((d, i) => (d, i)).ToDictionary(kv => kv.d, kv => kv.i);
/// <summary> /// <summary>
/// Returns if the given direction is considered an "adjacent" direction. /// Returns if the given direction is considered an "adjacent" direction.
/// An adjacent direction is one that is not a diagonal. /// An adjacent direction is one that is not a diagonal.
@ -190,26 +193,7 @@ namespace MLEM.Misc {
/// <param name="fortyFiveDegrees">Whether to rotate by 45 degrees. If this is false, the rotation is 90 degrees instead.</param> /// <param name="fortyFiveDegrees">Whether to rotate by 45 degrees. If this is false, the rotation is 90 degrees instead.</param>
/// <returns>The rotated direction</returns> /// <returns>The rotated direction</returns>
public static Direction2 RotateCw(this Direction2 dir, bool fortyFiveDegrees = false) { public static Direction2 RotateCw(this Direction2 dir, bool fortyFiveDegrees = false) {
switch (dir) { return Clockwise[(ClockwiseLookup[dir] + (fortyFiveDegrees ? 1 : 2)) % Clockwise.Length];
case Direction2.Up:
return fortyFiveDegrees ? Direction2.UpRight : Direction2.Right;
case Direction2.Right:
return fortyFiveDegrees ? Direction2.DownRight : Direction2.Down;
case Direction2.Down:
return fortyFiveDegrees ? Direction2.DownLeft : Direction2.Left;
case Direction2.Left:
return fortyFiveDegrees ? Direction2.UpLeft : Direction2.Up;
case Direction2.UpRight:
return fortyFiveDegrees ? Direction2.Right : Direction2.DownRight;
case Direction2.DownRight:
return fortyFiveDegrees ? Direction2.Down : Direction2.DownLeft;
case Direction2.DownLeft:
return fortyFiveDegrees ? Direction2.Left : Direction2.UpLeft;
case Direction2.UpLeft:
return fortyFiveDegrees ? Direction2.Up : Direction2.UpRight;
default:
return Direction2.None;
}
} }
/// <summary> /// <summary>
@ -219,26 +203,10 @@ namespace MLEM.Misc {
/// <param name="fortyFiveDegrees">Whether to rotate by 45 degrees. If this is false, the rotation is 90 degrees instead.</param> /// <param name="fortyFiveDegrees">Whether to rotate by 45 degrees. If this is false, the rotation is 90 degrees instead.</param>
/// <returns>The rotated direction</returns> /// <returns>The rotated direction</returns>
public static Direction2 RotateCcw(this Direction2 dir, bool fortyFiveDegrees = false) { public static Direction2 RotateCcw(this Direction2 dir, bool fortyFiveDegrees = false) {
switch (dir) { var index = ClockwiseLookup[dir] - (fortyFiveDegrees ? 1 : 2);
case Direction2.Up: if (index < 0)
return fortyFiveDegrees ? Direction2.UpLeft : Direction2.Left; index += Clockwise.Length;
case Direction2.Right: return Clockwise[index % Clockwise.Length];
return fortyFiveDegrees ? Direction2.UpRight : Direction2.Up;
case Direction2.Down:
return fortyFiveDegrees ? Direction2.DownRight : Direction2.Right;
case Direction2.Left:
return fortyFiveDegrees ? Direction2.DownLeft : Direction2.Down;
case Direction2.UpRight:
return fortyFiveDegrees ? Direction2.Up : Direction2.UpLeft;
case Direction2.DownRight:
return fortyFiveDegrees ? Direction2.Right : Direction2.UpRight;
case Direction2.DownLeft:
return fortyFiveDegrees ? Direction2.Down : Direction2.DownRight;
case Direction2.UpLeft:
return fortyFiveDegrees ? Direction2.Left : Direction2.DownLeft;
default:
return Direction2.None;
}
} }
/// <summary> /// <summary>
@ -269,5 +237,19 @@ namespace MLEM.Misc {
return offset.Y > 0 ? Direction2.Down : Direction2.Up; return offset.Y > 0 ? Direction2.Down : Direction2.Up;
} }
/// <summary>
/// Rotates the given direction by a given reference direction
/// </summary>
/// <param name="dir">The direction to rotate</param>
/// <param name="reference">The direction to rotate by</param>
/// <param name="start">The direction to use as the default direction</param>
/// <returns>The direction, rotated by the reference direction</returns>
public static Direction2 RotateBy(this Direction2 dir, Direction2 reference, Direction2 start = Direction2.Up) {
var diff = ClockwiseLookup[reference] - ClockwiseLookup[start];
if (diff < 0)
diff += Clockwise.Length;
return Clockwise[(ClockwiseLookup[dir] + diff) % Clockwise.Length];
}
} }
} }

View file

@ -1,22 +1,64 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using MLEM.Misc; using MLEM.Misc;
using NUnit.Framework; using NUnit.Framework;
using static MLEM.Misc.Direction2;
namespace Tests { namespace Tests {
public class DirectionTests { public class DirectionTests {
[Test] [Test]
public void TestDirections() { public void TestDirections() {
Assert.AreEqual(new Vector2(0.5F, 0.5F).ToDirection(), Direction2.DownRight); Assert.AreEqual(new Vector2(0.5F, 0.5F).ToDirection(), DownRight);
Assert.AreEqual(new Vector2(0.25F, 0.5F).ToDirection(), Direction2.DownRight); Assert.AreEqual(new Vector2(0.25F, 0.5F).ToDirection(), DownRight);
Assert.AreEqual(new Vector2(0.15F, 0.5F).ToDirection(), Direction2.Down); Assert.AreEqual(new Vector2(0.15F, 0.5F).ToDirection(), Down);
} }
[Test] [Test]
public void Test90Directions() { public void Test90Directions() {
Assert.AreEqual(new Vector2(0.75F, 0.5F).To90Direction(), Direction2.Right); Assert.AreEqual(new Vector2(0.75F, 0.5F).To90Direction(), Right);
Assert.AreEqual(new Vector2(0.5F, 0.5F).To90Direction(), Direction2.Down); Assert.AreEqual(new Vector2(0.5F, 0.5F).To90Direction(), Down);
Assert.AreEqual(new Vector2(0.25F, 0.5F).To90Direction(), Direction2.Down); Assert.AreEqual(new Vector2(0.25F, 0.5F).To90Direction(), Down);
}
[Test]
public void TestRotations() {
// rotate cw
Assert.AreEqual(Up.RotateCw(), Right);
Assert.AreEqual(Up.RotateCw(true), UpRight);
Assert.AreEqual(Left.RotateCw(), Up);
Assert.AreEqual(UpLeft.RotateCw(), UpRight);
// rotate ccw
Assert.AreEqual(Up.RotateCcw(), Left);
Assert.AreEqual(Up.RotateCcw(true), UpLeft);
Assert.AreEqual(Left.RotateCcw(), Down);
Assert.AreEqual(UpLeft.RotateCcw(), DownLeft);
// rotate 360 degrees
foreach (var dir in Direction2Helper.AllExceptNone) {
Assert.AreEqual(RotateMultipleTimes(dir, true, false, 4), dir);
Assert.AreEqual(RotateMultipleTimes(dir, true, true, 8), dir);
Assert.AreEqual(RotateMultipleTimes(dir, false, false, 4), dir);
Assert.AreEqual(RotateMultipleTimes(dir, false, true, 8), dir);
}
// rotate by with start Up
Assert.AreEqual(Right.RotateBy(Right), Down);
Assert.AreEqual(Right.RotateBy(Down), Left);
Assert.AreEqual(Right.RotateBy(Left), Up);
Assert.AreEqual(Right.RotateBy(Up), Right);
// rotate by with start Left
Assert.AreEqual(Up.RotateBy(Right, Left), Down);
Assert.AreEqual(Up.RotateBy(Down, Left), Left);
Assert.AreEqual(Up.RotateBy(Left, Left), Up);
Assert.AreEqual(Up.RotateBy(Up, Left), Right);
}
private static Direction2 RotateMultipleTimes(Direction2 dir, bool clockwise, bool fortyFiveDegrees, int times) {
for (var i = 0; i < times; i++)
dir = clockwise ? dir.RotateCw(fortyFiveDegrees) : dir.RotateCcw(fortyFiveDegrees);
return dir;
} }
} }