1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 09:07:25 +08:00

Cut distance snap lines at playfield border in catch editor

This commit is contained in:
ekrctb 2021-10-26 14:51:52 +09:00
parent c5d765029c
commit de7a908be2

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Lines; using osu.Framework.Graphics.Lines;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
@ -27,6 +28,8 @@ namespace osu.Game.Rulesets.Catch.Edit
public float StartX { get; set; } public float StartX { get; set; }
private const double max_vertical_line_length_in_time = CatchPlayfield.WIDTH / Catcher.BASE_SPEED * 2;
private readonly double[] velocities; private readonly double[] velocities;
private readonly List<Path> verticalPaths = new List<Path>(); private readonly List<Path> verticalPaths = new List<Path>();
@ -63,27 +66,42 @@ namespace osu.Game.Rulesets.Catch.Edit
{ {
base.Update(); base.Update();
float startY = hitObjectContainer.PositionAtTime(StartTime); double currentTime = hitObjectContainer.Time.Current;
for (int i = 0; i < velocities.Length; i++) for (int i = 0; i < velocities.Length; i++)
{ {
double velocity = velocities[i]; double velocity = velocities[i];
var verticalPath = verticalPaths[i];
// The line ends at the top of the screen. // The line ends at the top of the playfield.
double topScreenTime = hitObjectContainer.TimeAtPosition(-hitObjectContainer.DrawHeight, hitObjectContainer.Time.Current); double endTime = hitObjectContainer.TimeAtPosition(-hitObjectContainer.DrawHeight, currentTime);
double endTime = Math.Max(StartTime, topScreenTime);
float x = (float)((endTime - StartTime) * velocity); // Non-vertical lines are cut at the sides of the playfield.
float y = hitObjectContainer.PositionAtTime(endTime, StartTime); // Vertical lines are cut at some reasonable length.
if (velocity > 0)
endTime = Math.Min(endTime, StartTime + (CatchPlayfield.WIDTH - StartX) / velocity);
else if (velocity < 0)
endTime = Math.Min(endTime, StartTime + StartX / -velocity);
else
endTime = Math.Min(endTime, StartTime + max_vertical_line_length_in_time);
Vector2[] lineVertices = verticalLineVertices[i]; Vector2[] lineVertices = verticalLineVertices[i];
lineVertices[0] = new Vector2(StartX, startY); lineVertices[0] = calculatePosition(velocity, StartTime);
lineVertices[1] = lineVertices[0] + new Vector2(x, y); lineVertices[1] = calculatePosition(velocity, endTime);
var verticalPath = verticalPaths[i];
verticalPath.Vertices = verticalLineVertices[i]; verticalPath.Vertices = verticalLineVertices[i];
verticalPath.OriginPosition = verticalPath.PositionInBoundingBox(Vector2.Zero); verticalPath.OriginPosition = verticalPath.PositionInBoundingBox(Vector2.Zero);
} }
Vector2 calculatePosition(double velocity, double time)
{
// Don't draw inverted lines.
time = Math.Max(time, StartTime);
float x = StartX + (float)((time - StartTime) * velocity);
float y = hitObjectContainer.PositionAtTime(time, currentTime);
return new Vector2(x, y);
}
} }
[CanBeNull] [CanBeNull]