1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 04:02:59 +08:00

Merge branch 'master' into fix-barline-lifetimes

This commit is contained in:
Dean Herbert 2020-02-25 20:41:04 +09:00 committed by GitHub
commit d564440fe7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 160 additions and 74 deletions

View File

@ -54,6 +54,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.221.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.221.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.225.0" />
</ItemGroup>
</Project>

View File

@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Tests
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
{
AddStep("Show " + result.GetDescription(), () => SetContents(() =>
new DrawableManiaJudgement(new JudgementResult(new ConvertHitObject(), new Judgement()) { Type = result }, null)
new DrawableManiaJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,

View File

@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Tests
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
{
AddStep("Show " + result.GetDescription(), () => SetContents(() =>
new DrawableOsuJudgement(new JudgementResult(new ConvertHitObject(), new Judgement()) { Type = result }, null)
new DrawableOsuJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,

View File

@ -20,6 +20,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
private const int spacing = 32;
private const double preempt = 800;
public override bool RemoveWhenNotAlive => false;
/// <summary>
/// The start time of <see cref="Start"/>.
/// </summary>
@ -79,27 +81,31 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
drawableObject.HitObject.DefaultsApplied += scheduleRefresh;
}
private void scheduleRefresh() => Scheduler.AddOnce(refresh);
private void scheduleRefresh()
{
Scheduler.AddOnce(refresh);
}
private void refresh()
{
ClearInternal();
if (End == null)
return;
OsuHitObject osuStart = Start.HitObject;
OsuHitObject osuEnd = End.HitObject;
double startTime = osuStart.GetEndTime();
if (osuEnd.NewCombo)
return;
LifetimeStart = startTime;
if (osuStart is Spinner || osuEnd is Spinner)
OsuHitObject osuEnd = End?.HitObject;
if (osuEnd == null || osuEnd.NewCombo || osuStart is Spinner || osuEnd is Spinner)
{
// ensure we always set a lifetime for full LifetimeManagementContainer benefits
LifetimeEnd = LifetimeStart;
return;
}
Vector2 startPosition = osuStart.EndPosition;
Vector2 endPosition = osuEnd.Position;
double startTime = osuStart.GetEndTime();
double endTime = osuEnd.StartTime;
Vector2 distanceVector = endPosition - startPosition;
@ -107,6 +113,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
float rotation = (float)(Math.Atan2(distanceVector.Y, distanceVector.X) * (180 / Math.PI));
double duration = endTime - startTime;
double? firstTransformStartTime = null;
double finalTransformEndTime = startTime;
for (int d = (int)(spacing * 1.5); d < distance - spacing; d += spacing)
{
float fraction = (float)d / distance;
@ -125,16 +134,23 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
Scale = new Vector2(1.5f * osuEnd.Scale),
});
if (firstTransformStartTime == null)
firstTransformStartTime = fadeInTime;
using (fp.BeginAbsoluteSequence(fadeInTime))
{
fp.FadeIn(osuEnd.TimeFadeIn);
fp.ScaleTo(osuEnd.Scale, osuEnd.TimeFadeIn, Easing.Out);
fp.MoveTo(pointEndPosition, osuEnd.TimeFadeIn, Easing.Out);
fp.Delay(fadeOutTime - fadeInTime).FadeOut(osuEnd.TimeFadeIn);
}
fp.Expire(true);
finalTransformEndTime = fadeOutTime + osuEnd.TimeFadeIn;
}
}
// todo: use Expire() on FollowPoints and take lifetime from them when https://github.com/ppy/osu-framework/issues/3300 is fixed.
LifetimeStart = firstTransformStartTime ?? startTime;
LifetimeEnd = finalTransformEndTime;
}
}
}

View File

@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
/// <summary>
/// Visualises connections between <see cref="DrawableOsuHitObject"/>s.
/// </summary>
public class FollowPointRenderer : CompositeDrawable
public class FollowPointRenderer : LifetimeManagementContainer
{
/// <summary>
/// All the <see cref="FollowPointConnection"/>s contained by this <see cref="FollowPointRenderer"/>.
@ -45,8 +45,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
/// <returns>The index of <paramref name="connection"/> in <see cref="connections"/>.</returns>
private void addConnection(FollowPointConnection connection)
{
AddInternal(connection);
// Groups are sorted by their start time when added such that the index can be used to post-process other surrounding connections
int index = connections.AddInPlace(connection, Comparer<FollowPointConnection>.Create((g1, g2) => g1.StartTime.Value.CompareTo(g2.StartTime.Value)));
@ -74,6 +72,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
FollowPointConnection previousConnection = connections[index - 1];
previousConnection.End = connection.Start;
}
AddInternal(connection);
}
/// <summary>

View File

@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) };
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = hitResult });
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult });
}
private void addStrongHitJudgement(bool kiai)
@ -163,13 +163,13 @@ namespace osu.Game.Rulesets.Taiko.Tests
var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) };
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = hitResult });
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new ConvertHitObject(), new TaikoStrongJudgement()) { Type = HitResult.Great });
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult });
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new HitObject(), new TaikoStrongJudgement()) { Type = HitResult.Great });
}
private void addMissJudgement()
{
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = HitResult.Miss });
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = HitResult.Miss });
}
private void addBarLine(bool major, double delay = scroll_time)

View File

@ -11,8 +11,8 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Textures;
using osu.Framework.Testing;
using osu.Game.Audio;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Legacy;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Skinning;
using osu.Game.Tests.Visual;

View File

@ -27,9 +27,9 @@ namespace osu.Game.Tests.Gameplay
{
DrawableHitObject hitObject = null;
AddStep("setup", () => container.Add(new TestDrawableHitObject(new ConvertHitObject { StartTime = 500 })));
AddStep("setup", () => container.Add(new TestDrawableHitObject(new HitObject { StartTime = 500 })));
AddStep("add late hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new ConvertHitObject { StartTime = 1000 })));
AddStep("add late hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new HitObject { StartTime = 1000 })));
AddAssert("hitobject index is 0", () => container.IndexOf(hitObject) == 0);
}
@ -39,9 +39,9 @@ namespace osu.Game.Tests.Gameplay
{
DrawableHitObject hitObject = null;
AddStep("setup", () => container.Add(new TestDrawableHitObject(new ConvertHitObject { StartTime = 500 })));
AddStep("setup", () => container.Add(new TestDrawableHitObject(new HitObject { StartTime = 500 })));
AddStep("add early hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new ConvertHitObject())));
AddStep("add early hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new HitObject())));
AddAssert("hitobject index is 0", () => container.IndexOf(hitObject) == 1);
}
@ -54,8 +54,8 @@ namespace osu.Game.Tests.Gameplay
AddStep("setup", () =>
{
container.Add(firstObject = new TestDrawableHitObject(new ConvertHitObject()));
container.Add(secondObject = new TestDrawableHitObject(new ConvertHitObject { StartTime = 1000 }));
container.Add(firstObject = new TestDrawableHitObject(new HitObject()));
container.Add(secondObject = new TestDrawableHitObject(new HitObject { StartTime = 1000 }));
});
AddStep("move first object after second", () => firstObject.HitObject.StartTime = 2000);

View File

@ -20,6 +20,7 @@ using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Legacy;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.UI;
@ -163,7 +164,7 @@ namespace osu.Game.Tests.Visual.Gameplay
var beatmap = new Beatmap<HitObject> { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo } };
for (int i = 0; i < 10; i++)
beatmap.HitObjects.Add(new ConvertHitObject { StartTime = i * time_range });
beatmap.HitObjects.Add(new HitObject { StartTime = i * time_range });
return beatmap;
}

View File

@ -2,16 +2,17 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Rulesets.Objects;
using System;
using System.Collections.Generic;
using osu.Game.Rulesets.Judgements;
using osu.Framework.Utils;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Threading;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Catch.Scoring;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Scoring;
@ -43,6 +44,22 @@ namespace osu.Game.Tests.Visual.Gameplay
AddRepeatStep("New max negative", () => newJudgement(-hitWindows.WindowFor(HitResult.Meh)), 20);
AddRepeatStep("New max positive", () => newJudgement(hitWindows.WindowFor(HitResult.Meh)), 20);
AddStep("New fixed judgement (50ms)", () => newJudgement(50));
AddStep("Judgement barrage", () =>
{
int runCount = 0;
ScheduledDelegate del = null;
del = Scheduler.AddDelayed(() =>
{
newJudgement(runCount++ / 10f);
if (runCount == 500)
// ReSharper disable once AccessToModifiedClosure
del?.Cancel();
}, 10, true);
});
}
[Test]
@ -124,7 +141,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private void newJudgement(double offset = 0)
{
var judgement = new JudgementResult(new ConvertHitObject(), new Judgement())
var judgement = new JudgementResult(new HitObject(), new Judgement())
{
TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset,
Type = HitResult.Perfect,

View File

@ -224,7 +224,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private class TestDrawableControlPoint : DrawableHitObject<HitObject>
{
public TestDrawableControlPoint(ScrollingDirection direction, double time)
: base(new ConvertHitObject { StartTime = time })
: base(new HitObject { StartTime = time })
{
Origin = Anchor.Centre;
@ -255,7 +255,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private class TestDrawableHitObject : DrawableHitObject<HitObject>
{
public TestDrawableHitObject(double time)
: base(new ConvertHitObject { StartTime = time })
: base(new HitObject { StartTime = time })
{
Origin = Anchor.Custom;
OriginPosition = new Vector2(75 / 4.0f);

View File

@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
var objects = new List<HitObject>();
for (double i = 0; i < 5000; i += RNG.NextDouble() * 10 + i / 1000)
objects.Add(new ConvertHitObject { StartTime = i });
objects.Add(new HitObject { StartTime = i });
replaceObjects(objects);
}
@ -132,7 +132,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
var objects = new List<HitObject>();
for (double i = 0; i < 5000; i++)
objects.Add(new ConvertHitObject { StartTime = i });
objects.Add(new HitObject { StartTime = i });
replaceObjects(objects);
}

View File

@ -13,6 +13,8 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osuTK;
using JetBrains.Annotations;
using NUnit.Framework;
namespace osu.Game.Tests.Visual.Online
{
@ -30,6 +32,8 @@ namespace osu.Game.Tests.Visual.Online
private readonly BindableBool showDeleted = new BindableBool();
private readonly Container content;
private TestCommentsPage commentsPage;
public TestSceneCommentsPage()
{
Add(new FillFlowContainer
@ -57,15 +61,29 @@ namespace osu.Game.Tests.Visual.Online
}
}
});
}
AddStep("load comments", () => createPage(getCommentBundle()));
AddStep("load empty comments", () => createPage(getEmptyCommentBundle()));
[Test]
public void TestAppendDuplicatedComment()
{
AddStep("Create page", () => createPage(getCommentBundle()));
AddAssert("Dictionary length is 10", () => commentsPage?.DictionaryLength == 10);
AddStep("Append existing comment", () => commentsPage?.AppendComments(getCommentSubBundle()));
AddAssert("Dictionary length is 10", () => commentsPage?.DictionaryLength == 10);
}
[Test]
public void TestEmptyBundle()
{
AddStep("Create page", () => createPage(getEmptyCommentBundle()));
AddAssert("Dictionary length is 0", () => commentsPage?.DictionaryLength == 0);
}
private void createPage(CommentBundle commentBundle)
{
commentsPage = null;
content.Clear();
content.Add(new CommentsPage(commentBundle)
content.Add(commentsPage = new TestCommentsPage(commentBundle)
{
ShowDeleted = { BindTarget = showDeleted }
});
@ -182,5 +200,33 @@ namespace osu.Game.Tests.Visual.Online
}
},
};
private CommentBundle getCommentSubBundle() => new CommentBundle
{
Comments = new List<Comment>
{
new Comment
{
Id = 1,
Message = "Simple test comment",
LegacyName = "TestUser1",
CreatedAt = DateTimeOffset.Now,
VotesCount = 5
},
},
IncludedComments = new List<Comment>(),
};
private class TestCommentsPage : CommentsPage
{
public TestCommentsPage(CommentBundle commentBundle)
: base(commentBundle)
{
}
public new void AppendComments([NotNull] CommentBundle bundle) => base.AppendComments(bundle);
public int DictionaryLength => CommentDictionary.Count;
}
}
}

View File

@ -13,6 +13,7 @@ using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Legacy;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Taiko;

View File

@ -64,7 +64,7 @@ namespace osu.Game.Graphics.UserInterface
protected override void Update()
{
base.Update();
MainContents.Size = new Vector2(Math.Min(100, Math.Min(DrawWidth, DrawHeight) * 0.25f));
MainContents.Size = new Vector2(Math.Clamp(Math.Min(DrawWidth, DrawHeight) * 0.25f, 30, 100));
}
protected override void Dispose(bool isDisposing)

View File

@ -93,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface
private void rotate()
{
spinner.Spin(spin_duration * 4, RotationDirection.Clockwise);
spinner.Spin(spin_duration * 3.5f, RotationDirection.Clockwise);
MainContents.RotateTo(0).Then()
.RotateTo(90, spin_duration, Easing.InOutQuart).Then()

View File

@ -61,15 +61,15 @@ namespace osu.Game.Overlays.Comments
return;
}
appendComments(commentBundle);
AppendComments(commentBundle);
}
private DrawableComment getDrawableComment(Comment comment)
{
if (commentDictionary.TryGetValue(comment.Id, out var existing))
if (CommentDictionary.TryGetValue(comment.Id, out var existing))
return existing;
return commentDictionary[comment.Id] = new DrawableComment(comment)
return CommentDictionary[comment.Id] = new DrawableComment(comment)
{
ShowDeleted = { BindTarget = ShowDeleted },
Sort = { BindTarget = Sort },
@ -81,31 +81,28 @@ namespace osu.Game.Overlays.Comments
{
var request = new GetCommentsRequest(CommentableId.Value, Type.Value, Sort.Value, page, drawableComment.Comment.Id);
request.Success += response => Schedule(() => appendComments(response));
request.Success += response => Schedule(() => AppendComments(response));
api.PerformAsync(request);
}
private readonly Dictionary<long, DrawableComment> commentDictionary = new Dictionary<long, DrawableComment>();
protected readonly Dictionary<long, DrawableComment> CommentDictionary = new Dictionary<long, DrawableComment>();
/// <summary>
/// Appends retrieved comments to the subtree rooted of comments in this page.
/// </summary>
/// <param name="bundle">The bundle of comments to add.</param>
private void appendComments([NotNull] CommentBundle bundle)
protected void AppendComments([NotNull] CommentBundle bundle)
{
var orphaned = new List<Comment>();
foreach (var topLevel in bundle.Comments)
addNewComment(topLevel);
foreach (var child in bundle.IncludedComments)
foreach (var comment in bundle.Comments.Concat(bundle.IncludedComments))
{
// Included comments can contain the parent comment, which already exists in the hierarchy.
if (commentDictionary.ContainsKey(child.Id))
// Exclude possible duplicated comments.
if (CommentDictionary.ContainsKey(comment.Id))
continue;
addNewComment(child);
addNewComment(comment);
}
// Comments whose parents were seen later than themselves can now be added.
@ -121,7 +118,7 @@ namespace osu.Game.Overlays.Comments
// Comments that have no parent are added as top-level comments to the flow.
flow.Add(drawableComment);
}
else if (commentDictionary.TryGetValue(comment.ParentId.Value, out var parentDrawable))
else if (CommentDictionary.TryGetValue(comment.ParentId.Value, out var parentDrawable))
{
// The comment's parent has already been seen, so the parent<-> child links can be added.
comment.ParentComment = parentDrawable.Comment;

View File

@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects
/// HitObjects may contain more properties for which you should be checking through the IHas* types.
/// </para>
/// </summary>
public abstract class HitObject
public class HitObject
{
/// <summary>
/// A small adjustment to the start time of control points to account for rounding/precision errors.
@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Objects
[JsonIgnore]
public IReadOnlyList<HitObject> NestedHitObjects => nestedHitObjects;
protected HitObject()
public HitObject()
{
StartTimeBindable.ValueChanged += time =>
{
@ -144,10 +144,9 @@ namespace osu.Game.Rulesets.Objects
/// <summary>
/// Creates the <see cref="Judgement"/> that represents the scoring information for this <see cref="HitObject"/>.
/// Used to decide on drawable object lifetimes.
/// </summary>
[NotNull]
public abstract Judgement CreateJudgement();
public virtual Judgement CreateJudgement() => new Judgement();
/// <summary>
/// Creates the <see cref="HitWindows"/> for this <see cref="HitObject"/>.
@ -157,7 +156,7 @@ namespace osu.Game.Rulesets.Objects
/// </para>
/// </summary>
[NotNull]
protected abstract HitWindows CreateHitWindows();
protected virtual HitWindows CreateHitWindows() => new HitWindows();
}
public static class HitObjectExtensions

View File

@ -4,12 +4,12 @@
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Objects
namespace osu.Game.Rulesets.Objects.Legacy
{
/// <summary>
/// A hit object only used for conversion, not actual gameplay.
/// </summary>
public class ConvertHitObject : HitObject
internal abstract class ConvertHitObject : HitObject
{
public override Judgement CreateJudgement() => new IgnoreJudgement();

View File

@ -15,7 +15,6 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play.HUD;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Play
{
@ -63,15 +62,9 @@ namespace osu.Game.Screens.Play
set
{
if (value)
{
loading.Show();
backgroundSprite.FadeColour(OsuColour.Gray(0.5f), 400, Easing.OutQuint);
}
else
{
loading.Hide();
backgroundSprite.FadeColour(Color4.White, 400, Easing.OutQuint);
}
}
}
@ -138,7 +131,7 @@ namespace osu.Game.Screens.Play
Anchor = Anchor.Centre,
FillMode = FillMode.Fill,
},
loading = new LoadingSpinner { Scale = new Vector2(1.3f) }
loading = new LoadingLayer(backgroundSprite)
}
},
new OsuSpriteText

View File

@ -207,11 +207,27 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
private double floatingAverage;
private Container colourBars;
private const int max_concurrent_judgements = 50;
public override void OnNewJudgement(JudgementResult judgement)
{
if (!judgement.IsHit)
return;
if (judgementsContainer.Count > max_concurrent_judgements)
{
const double quick_fade_time = 100;
// check with a bit of lenience to avoid precision error in comparison.
var old = judgementsContainer.FirstOrDefault(j => j.LifetimeEnd > Clock.CurrentTime + quick_fade_time * 1.1);
if (old != null)
{
old.ClearTransforms();
old.FadeOut(quick_fade_time).Expire();
}
}
judgementsContainer.Add(new JudgementLine
{
Y = getRelativeJudgementPosition(judgement.TimeOffset),
@ -228,7 +244,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
private class JudgementLine : CompositeDrawable
{
private const int judgement_fade_duration = 10000;
private const int judgement_fade_duration = 5000;
public JudgementLine()
{
@ -255,7 +271,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
Width = 0;
this.ResizeWidthTo(1, 200, Easing.OutElasticHalf);
this.FadeTo(0.8f, 150).Then().FadeOut(judgement_fade_duration, Easing.OutQuint).Expire();
this.FadeTo(0.8f, 150).Then().FadeOut(judgement_fade_duration).Expire();
}
}
}

View File

@ -23,7 +23,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.221.0" />
<PackageReference Include="ppy.osu.Framework" Version="2020.221.0" />
<PackageReference Include="ppy.osu.Framework" Version="2020.225.0" />
<PackageReference Include="Sentry" Version="2.0.3" />
<PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" />

View File

@ -74,7 +74,7 @@
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.221.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.221.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.225.0" />
</ItemGroup>
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
<ItemGroup Label="Transitive Dependencies">
@ -82,7 +82,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Framework" Version="2020.221.0" />
<PackageReference Include="ppy.osu.Framework" Version="2020.225.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />