mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 09:23:06 +08:00
Merge pull request #20941 from peppy/fix-distance-snap-offset
Offset start of distance snap grid drawing if reference object's start time doesn't align
This commit is contained in:
commit
72b594d72e
@ -4,12 +4,15 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Overlays;
|
||||
@ -52,6 +55,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
};
|
||||
|
||||
private OsuDistanceSnapGrid grid;
|
||||
private SnappingCursorContainer cursor;
|
||||
|
||||
public TestSceneOsuDistanceSnapGrid()
|
||||
{
|
||||
@ -88,8 +92,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.SlateGray
|
||||
},
|
||||
cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position },
|
||||
grid = new OsuDistanceSnapGrid(new HitCircle { Position = grid_position }),
|
||||
new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }
|
||||
};
|
||||
});
|
||||
|
||||
@ -154,6 +158,37 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
assertSnappedDistance(expectedDistance);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestReferenceObjectNotOnSnapGrid()
|
||||
{
|
||||
AddStep("create grid", () =>
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.SlateGray
|
||||
},
|
||||
cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position },
|
||||
grid = new OsuDistanceSnapGrid(new HitCircle
|
||||
{
|
||||
Position = grid_position,
|
||||
// This is important. It sets the reference object to a point in time that isn't on the current snap divisor's grid.
|
||||
// We are testing that the grid's display is offset correctly.
|
||||
StartTime = 40,
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
AddStep("move mouse to point", () => InputManager.MoveMouseTo(grid.ToScreenSpace(grid_position + new Vector2(beat_length, 0) * 2)));
|
||||
|
||||
AddAssert("Ensure cursor is on a grid line", () =>
|
||||
{
|
||||
return grid.ChildrenOfType<CircularProgress>().Any(p => Precision.AlmostEquals(p.ScreenSpaceDrawQuad.TopRight.X, grid.ToScreenSpace(cursor.LastSnappedPosition).X));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLimitedDistance()
|
||||
{
|
||||
@ -166,8 +201,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.SlateGray
|
||||
},
|
||||
cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position },
|
||||
grid = new OsuDistanceSnapGrid(new HitCircle { Position = grid_position }, new HitCircle { StartTime = 200 }),
|
||||
new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }
|
||||
};
|
||||
});
|
||||
|
||||
@ -186,6 +221,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
{
|
||||
public Func<Vector2, Vector2> GetSnapPosition;
|
||||
|
||||
public Vector2 LastSnappedPosition { get; private set; }
|
||||
|
||||
private readonly Drawable cursor;
|
||||
|
||||
private InputManager inputManager;
|
||||
@ -214,7 +251,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
cursor.Position = GetSnapPosition.Invoke(inputManager.CurrentState.Mouse.Position);
|
||||
cursor.Position = LastSnappedPosition = GetSnapPosition.Invoke(inputManager.CurrentState.Mouse.Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,9 +53,16 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
float maxDistance = new Vector2(dx, dy).Length;
|
||||
int requiredCircles = Math.Min(MaxIntervals, (int)(maxDistance / DistanceBetweenTicks));
|
||||
|
||||
// We need to offset the drawn lines to the next valid snap for the currently selected divisor.
|
||||
//
|
||||
// Picture the scenario where the user has just placed an object on a 1/2 snap, then changes to
|
||||
// 1/3 snap and expects to be able to place the next object on a valid 1/3 snap, regardless of the
|
||||
// fact that the 1/2 snap reference object is not valid for 1/3 snapping.
|
||||
float offset = SnapProvider.FindSnappedDistance(ReferenceObject, 0);
|
||||
|
||||
for (int i = 0; i < requiredCircles; i++)
|
||||
{
|
||||
float diameter = (i + 1) * DistanceBetweenTicks * 2;
|
||||
float diameter = (offset + (i + 1) * DistanceBetweenTicks) * 2;
|
||||
|
||||
AddInternal(new Ring(ReferenceObject, GetColourForIndexFromPlacement(i))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user