1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-05-10 19:38:43 +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)
### MLEM
Additions
- Added RotateBy to Direction2Helper
Fixes
- Set default values for InputHandler held and pressed keys to avoid an exception if buttons are held in the very first frame
Improvements
- Improved NinePatch memory performance
- Moved sound-related classes into Sound namespace
### MLEM.Ui
Fixes

View file

@ -85,6 +85,9 @@ namespace MLEM.Misc {
/// </summary>
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>
/// Returns if the given direction is considered an "adjacent" direction.
/// 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>
/// <returns>The rotated direction</returns>
public static Direction2 RotateCw(this Direction2 dir, bool fortyFiveDegrees = false) {
switch (dir) {
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;
}
return Clockwise[(ClockwiseLookup[dir] + (fortyFiveDegrees ? 1 : 2)) % Clockwise.Length];
}
/// <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>
/// <returns>The rotated direction</returns>
public static Direction2 RotateCcw(this Direction2 dir, bool fortyFiveDegrees = false) {
switch (dir) {
case Direction2.Up:
return fortyFiveDegrees ? Direction2.UpLeft : Direction2.Left;
case Direction2.Right:
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;
}
var index = ClockwiseLookup[dir] - (fortyFiveDegrees ? 1 : 2);
if (index < 0)
index += Clockwise.Length;
return Clockwise[index % Clockwise.Length];
}
/// <summary>
@ -269,5 +237,19 @@ namespace MLEM.Misc {
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 MLEM.Misc;
using NUnit.Framework;
using static MLEM.Misc.Direction2;
namespace Tests {
public class DirectionTests {
[Test]
public void TestDirections() {
Assert.AreEqual(new Vector2(0.5F, 0.5F).ToDirection(), Direction2.DownRight);
Assert.AreEqual(new Vector2(0.25F, 0.5F).ToDirection(), Direction2.DownRight);
Assert.AreEqual(new Vector2(0.15F, 0.5F).ToDirection(), Direction2.Down);
Assert.AreEqual(new Vector2(0.5F, 0.5F).ToDirection(), DownRight);
Assert.AreEqual(new Vector2(0.25F, 0.5F).ToDirection(), DownRight);
Assert.AreEqual(new Vector2(0.15F, 0.5F).ToDirection(), Down);
}
[Test]
public void Test90Directions() {
Assert.AreEqual(new Vector2(0.75F, 0.5F).To90Direction(), Direction2.Right);
Assert.AreEqual(new Vector2(0.5F, 0.5F).To90Direction(), Direction2.Down);
Assert.AreEqual(new Vector2(0.25F, 0.5F).To90Direction(), Direction2.Down);
Assert.AreEqual(new Vector2(0.75F, 0.5F).To90Direction(), Right);
Assert.AreEqual(new Vector2(0.5F, 0.5F).To90Direction(), 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;
}
}