mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 04:53:29 +01:00
added Direction2Helper.RotateBy
This commit is contained in:
parent
d1b229b589
commit
f352e6b437
3 changed files with 74 additions and 46 deletions
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue