mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 13:23:22 +08:00
Rework scroller to support backwards playback
This commit is contained in:
parent
e9804bf11b
commit
949e17cc0e
@ -3,6 +3,7 @@
|
||||
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Skinning;
|
||||
@ -12,11 +13,28 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||
{
|
||||
public class TestSceneTaikoScroller : TaikoSkinnableTestScene
|
||||
{
|
||||
private readonly ManualClock clock = new ManualClock();
|
||||
|
||||
private bool reversed;
|
||||
|
||||
public TestSceneTaikoScroller()
|
||||
{
|
||||
AddStep("Load scroller", () => SetContents(() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoScroller), _ => Empty())));
|
||||
AddStep("Load scroller", () => SetContents(() =>
|
||||
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoScroller), _ => Empty())
|
||||
{
|
||||
Clock = new FramedClock(clock)
|
||||
}));
|
||||
AddToggleStep("Toggle passing", passing => this.ChildrenOfType<LegacyTaikoScroller>().ForEach(s => s.LastResult.Value =
|
||||
new JudgementResult(null, new Judgement()) { Type = passing ? HitResult.Perfect : HitResult.Miss }));
|
||||
|
||||
AddToggleStep("toggle playback direction", reversed => this.reversed = reversed);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
clock.CurrentTime += (reversed ? -1 : 1) * Clock.ElapsedFrameTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning
|
||||
{
|
||||
public class LegacyTaikoScroller : CompositeDrawable
|
||||
{
|
||||
[Resolved(canBeNull: true)]
|
||||
private GameplayClock gameplayClock { get; set; }
|
||||
|
||||
public LegacyTaikoScroller()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
@ -59,31 +56,42 @@ namespace osu.Game.Rulesets.Taiko.Skinning
|
||||
{
|
||||
base.Update();
|
||||
|
||||
while (true)
|
||||
bool wideEnough() =>
|
||||
InternalChildren.Any()
|
||||
&& InternalChildren.First().ScreenSpaceDrawQuad.Width * InternalChildren.Count >= ScreenSpaceDrawQuad.Width * 2;
|
||||
|
||||
// store X before checking wide enough so if we perform layout there is no positional discrepancy.
|
||||
float currentX = (InternalChildren?.FirstOrDefault()?.X ?? 0) - (float)Clock.ElapsedFrameTime * 0.1f;
|
||||
|
||||
// ensure we have enough sprites
|
||||
if (!wideEnough())
|
||||
{
|
||||
float? additiveX = null;
|
||||
ClearInternal();
|
||||
|
||||
foreach (var sprite in InternalChildren)
|
||||
{
|
||||
// add the x coordinates and perform re-layout on all sprites as spacing may change with gameplay scale.
|
||||
sprite.X = additiveX ??= sprite.X - (float)(gameplayClock ?? Clock).ElapsedFrameTime * 0.1f;
|
||||
while (!wideEnough())
|
||||
AddInternal(new ScrollerSprite { Passing = passing });
|
||||
}
|
||||
|
||||
additiveX += sprite.DrawWidth - 1;
|
||||
var first = InternalChildren.First();
|
||||
var last = InternalChildren.Last();
|
||||
|
||||
if (sprite.X + sprite.DrawWidth < 0)
|
||||
sprite.Expire();
|
||||
}
|
||||
foreach (var sprite in InternalChildren)
|
||||
{
|
||||
// add the x coordinates and perform re-layout on all sprites as spacing may change with gameplay scale.
|
||||
sprite.X = currentX;
|
||||
currentX += sprite.DrawWidth - 1;
|
||||
}
|
||||
|
||||
var last = InternalChildren.LastOrDefault();
|
||||
if (first.ScreenSpaceDrawQuad.TopLeft.X >= ScreenSpaceDrawQuad.TopLeft.X)
|
||||
{
|
||||
foreach (var internalChild in InternalChildren)
|
||||
internalChild.X -= first.DrawWidth;
|
||||
}
|
||||
|
||||
// only break from this loop once we have saturated horizontal space completely.
|
||||
if (last != null && last.ScreenSpaceDrawQuad.TopRight.X >= ScreenSpaceDrawQuad.TopRight.X)
|
||||
break;
|
||||
|
||||
AddInternal(new ScrollerSprite
|
||||
{
|
||||
Passing = passing
|
||||
});
|
||||
if (last.ScreenSpaceDrawQuad.TopRight.X <= ScreenSpaceDrawQuad.TopRight.X)
|
||||
{
|
||||
foreach (var internalChild in InternalChildren)
|
||||
internalChild.X += first.DrawWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
new BarLineGenerator<BarLine>(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar.Major ? new DrawableBarLineMajor(bar) : new DrawableBarLine(bar)));
|
||||
|
||||
AddInternal(scroller = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoScroller), _ => Empty())
|
||||
FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoScroller), _ => Empty())
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Depth = float.MaxValue
|
||||
|
Loading…
Reference in New Issue
Block a user