Move rest of ScrollingPlayfield into ScrollingRulesetContainer

This commit is contained in:
smoogipoo
2018-11-07 17:24:05 +09:00
parent e7969ecec7
commit 10543cf1b6
16 changed files with 104 additions and 113 deletions

View File

@ -20,8 +20,6 @@ namespace osu.Game.Rulesets.Catch.UI
private readonly CatcherArea catcherArea; private readonly CatcherArea catcherArea;
protected override bool UserScrollSpeedAdjustment => false;
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation) public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
{ {
Container explodingFruitContainer; Container explodingFruitContainer;
@ -50,8 +48,6 @@ namespace osu.Game.Rulesets.Catch.UI
HitObjectContainer HitObjectContainer
} }
}; };
VisibleTimeRange.Value = BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
} }
public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj); public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj);

View File

@ -21,10 +21,13 @@ namespace osu.Game.Rulesets.Catch.UI
{ {
protected override ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Constant; protected override ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Constant;
protected override bool UserScrollSpeedAdjustment => false;
public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
Direction.Value = ScrollingDirection.Down; Direction.Value = ScrollingDirection.Down;
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
} }
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this); public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);

View File

@ -94,7 +94,6 @@ namespace osu.Game.Rulesets.Mania.Tests
Height = 0.85f, Height = 0.85f,
AccentColour = Color4.OrangeRed, AccentColour = Color4.OrangeRed,
Action = { Value = action }, Action = { Value = action },
VisibleTimeRange = { Value = 2000 }
}; };
columns.Add(column); columns.Add(column);
@ -105,6 +104,7 @@ namespace osu.Game.Rulesets.Mania.Tests
Origin = Anchor.Centre, Origin = Anchor.Centre,
AutoSizeAxes = Axes.X, AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
TimeRange = 2000,
Child = column Child = column
}; };
} }

View File

@ -123,7 +123,7 @@ namespace osu.Game.Rulesets.Mania.Tests
{ {
var specialAction = ManiaAction.Special1; var specialAction = ManiaAction.Special1;
var stage = new ManiaStage(0, new StageDefinition { Columns = 2 }, ref action, ref specialAction) { VisibleTimeRange = { Value = 2000 } }; var stage = new ManiaStage(0, new StageDefinition { Columns = 2 }, ref action, ref specialAction);
stages.Add(stage); stages.Add(stage);
return new ScrollingTestContainer(direction) return new ScrollingTestContainer(direction)
@ -132,6 +132,7 @@ namespace osu.Game.Rulesets.Mania.Tests
Origin = Anchor.Centre, Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X, AutoSizeAxes = Axes.X,
TimeRange = 2000,
Child = stage Child = stage
}; };
} }

View File

@ -1,12 +1,12 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Mania.UI
hitObject.AccentColour = AccentColour; hitObject.AccentColour = AccentColour;
hitObject.OnNewResult += OnNewResult; hitObject.OnNewResult += OnNewResult;
HitObjects.Add(hitObject); HitObjectContainer.Add(hitObject);
} }
internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result) internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
@ -154,10 +154,10 @@ namespace osu.Game.Rulesets.Mania.UI
return false; return false;
var nextObject = var nextObject =
HitObjects.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ?? HitObjectContainer.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ??
// fallback to non-alive objects to find next off-screen object // fallback to non-alive objects to find next off-screen object
HitObjects.Objects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ?? HitObjectContainer.Objects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ??
HitObjects.Objects.LastOrDefault(); HitObjectContainer.Objects.LastOrDefault();
nextObject?.PlaySamples(); nextObject?.PlaySamples();

View File

@ -1,13 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
@ -42,7 +40,6 @@ namespace osu.Game.Rulesets.Mania.UI
for (int i = 0; i < stageDefinitions.Count; i++) for (int i = 0; i < stageDefinitions.Count; i++)
{ {
var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction); var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
newStage.VisibleTimeRange.BindTo(VisibleTimeRange);
playfieldGrid.Content[0][i] = newStage; playfieldGrid.Content[0][i] = newStage;
@ -69,11 +66,5 @@ namespace osu.Game.Rulesets.Mania.UI
return null; return null;
} }
[BackgroundDependencyLoader]
private void load(ManiaConfigManager maniaConfig)
{
maniaConfig.BindWith(ManiaSetting.ScrollTime, VisibleTimeRange);
}
} }
} }

View File

@ -76,6 +76,8 @@ namespace osu.Game.Rulesets.Mania.UI
Config.BindWith(ManiaSetting.ScrollDirection, configDirection); Config.BindWith(ManiaSetting.ScrollDirection, configDirection);
configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true); configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true);
Config.BindWith(ManiaSetting.ScrollTime, TimeRange);
} }
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages) protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)

View File

@ -144,8 +144,6 @@ namespace osu.Game.Rulesets.Mania.UI
public void AddColumn(Column c) public void AddColumn(Column c)
{ {
c.VisibleTimeRange.BindTo(VisibleTimeRange);
topLevelContainer.Add(c.TopLevelContainer.CreateProxy()); topLevelContainer.Add(c.TopLevelContainer.CreateProxy());
columnFlow.Add(c); columnFlow.Add(c);
AddNested(c); AddNested(c);

View File

@ -38,8 +38,6 @@ namespace osu.Game.Rulesets.Taiko.UI
/// </summary> /// </summary>
private const float left_area_size = 240; private const float left_area_size = 240;
protected override bool UserScrollSpeedAdjustment => false;
private readonly Container<HitExplosion> hitExplosionContainer; private readonly Container<HitExplosion> hitExplosionContainer;
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer; private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
private readonly JudgementContainer<DrawableTaikoJudgement> judgementContainer; private readonly JudgementContainer<DrawableTaikoJudgement> judgementContainer;
@ -195,8 +193,6 @@ namespace osu.Game.Rulesets.Taiko.UI
} }
} }
}; };
VisibleTimeRange.Value = 7000;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -24,10 +24,13 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
protected override ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Overlapping; protected override ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Overlapping;
protected override bool UserScrollSpeedAdjustment => false;
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap) : base(ruleset, beatmap)
{ {
Direction.Value = ScrollingDirection.Left; Direction.Value = ScrollingDirection.Left;
TimeRange.Value = 7000;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual
AddStep("Overlapping scroll", () => setScrollAlgorithm(ScrollAlgorithm.Overlapping)); AddStep("Overlapping scroll", () => setScrollAlgorithm(ScrollAlgorithm.Overlapping));
AddStep("Sequential scroll", () => setScrollAlgorithm(ScrollAlgorithm.Sequential)); AddStep("Sequential scroll", () => setScrollAlgorithm(ScrollAlgorithm.Sequential));
AddSliderStep("Time range", 100, 10000, 5000, v => playfields.ForEach(p => p.VisibleTimeRange.Value = v)); AddSliderStep("Time range", 100, 10000, 5000, v => scrollContainers.ForEach(c => c.TimeRange = v));
AddStep("Add control point", () => addControlPoint(Time.Current + 5000)); AddStep("Add control point", () => addControlPoint(Time.Current + 5000));
} }

View File

@ -14,6 +14,11 @@ namespace osu.Game.Rulesets.UI.Scrolling
/// </summary> /// </summary>
IBindable<ScrollingDirection> Direction { get; } IBindable<ScrollingDirection> Direction { get; }
/// <summary>
///
/// </summary>
IBindable<double> TimeRange { get; }
/// <summary> /// <summary>
/// The algorithm which controls <see cref="HitObject"/> positions and sizes. /// The algorithm which controls <see cref="HitObject"/> positions and sizes.
/// </summary> /// </summary>

View File

@ -12,14 +12,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
{ {
public class ScrollingHitObjectContainer : HitObjectContainer public class ScrollingHitObjectContainer : HitObjectContainer
{ {
/// <summary> private readonly IBindable<double> timeRange = new BindableDouble();
/// The duration required to scroll through one length of the <see cref="ScrollingHitObjectContainer"/> before any control point adjustments.
/// </summary>
public readonly BindableDouble TimeRange = new BindableDouble
{
MinValue = 0,
MaxValue = double.MaxValue
};
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>(); private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
@ -31,15 +24,16 @@ namespace osu.Game.Rulesets.UI.Scrolling
public ScrollingHitObjectContainer() public ScrollingHitObjectContainer()
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
TimeRange.ValueChanged += _ => initialStateCache.Invalidate();
direction.ValueChanged += _ => initialStateCache.Invalidate();
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
direction.BindTo(scrollingInfo.Direction); direction.BindTo(scrollingInfo.Direction);
timeRange.BindTo(scrollingInfo.TimeRange);
direction.ValueChanged += _ => initialStateCache.Invalidate();
timeRange.ValueChanged += _ => initialStateCache.Invalidate();
} }
public override void Add(DrawableHitObject hitObject) public override void Add(DrawableHitObject hitObject)
@ -93,7 +87,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
private void computeInitialStateRecursive(DrawableHitObject hitObject) private void computeInitialStateRecursive(DrawableHitObject hitObject)
{ {
hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, TimeRange); hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value);
if (hitObject.HitObject is IHasEndTime endTime) if (hitObject.HitObject is IHasEndTime endTime)
{ {
@ -101,11 +95,11 @@ namespace osu.Game.Rulesets.UI.Scrolling
{ {
case ScrollingDirection.Up: case ScrollingDirection.Up:
case ScrollingDirection.Down: case ScrollingDirection.Down:
hitObject.Height = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, TimeRange, scrollLength); hitObject.Height = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, timeRange.Value, scrollLength);
break; break;
case ScrollingDirection.Left: case ScrollingDirection.Left:
case ScrollingDirection.Right: case ScrollingDirection.Right:
hitObject.Width = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, TimeRange, scrollLength); hitObject.Width = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, timeRange.Value, scrollLength);
break; break;
} }
} }
@ -133,16 +127,16 @@ namespace osu.Game.Rulesets.UI.Scrolling
switch (direction.Value) switch (direction.Value)
{ {
case ScrollingDirection.Up: case ScrollingDirection.Up:
hitObject.Y = scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, TimeRange, scrollLength); hitObject.Y = scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
break; break;
case ScrollingDirection.Down: case ScrollingDirection.Down:
hitObject.Y = -scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, TimeRange, scrollLength); hitObject.Y = -scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
break; break;
case ScrollingDirection.Left: case ScrollingDirection.Left:
hitObject.X = scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, TimeRange, scrollLength); hitObject.X = scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
break; break;
case ScrollingDirection.Right: case ScrollingDirection.Right:
hitObject.X = -scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, TimeRange, scrollLength); hitObject.X = -scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
break; break;
} }
} }

View File

@ -3,9 +3,6 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.UI.Scrolling namespace osu.Game.Rulesets.UI.Scrolling
@ -13,52 +10,10 @@ namespace osu.Game.Rulesets.UI.Scrolling
/// <summary> /// <summary>
/// A type of <see cref="Playfield"/> specialized towards scrolling <see cref="DrawableHitObject"/>s. /// A type of <see cref="Playfield"/> specialized towards scrolling <see cref="DrawableHitObject"/>s.
/// </summary> /// </summary>
public abstract class ScrollingPlayfield : Playfield, IKeyBindingHandler<GlobalAction> public abstract class ScrollingPlayfield : Playfield
{ {
/// <summary>
/// The default span of time visible by the length of the scrolling axes.
/// This is clamped between <see cref="time_span_min"/> and <see cref="time_span_max"/>.
/// </summary>
private const double time_span_default = 1500;
/// <summary>
/// The minimum span of time that may be visible by the length of the scrolling axes.
/// </summary>
private const double time_span_min = 50;
/// <summary>
/// The maximum span of time that may be visible by the length of the scrolling axes.
/// </summary>
private const double time_span_max = 10000;
/// <summary>
/// The step increase/decrease of the span of time visible by the length of the scrolling axes.
/// </summary>
private const double time_span_step = 200;
/// <summary>
/// The span of time that is visible by the length of the scrolling axes.
/// For example, only hit objects with start time less than or equal to 1000 will be visible with <see cref="VisibleTimeRange"/> = 1000.
/// </summary>
public readonly BindableDouble VisibleTimeRange = new BindableDouble(time_span_default)
{
Default = time_span_default,
MinValue = time_span_min,
MaxValue = time_span_max
};
/// <summary>
/// Whether the player can change <see cref="VisibleTimeRange"/>.
/// </summary>
protected virtual bool UserScrollSpeedAdjustment => true;
protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>(); protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
/// <summary>
/// The container that contains the <see cref="DrawableHitObject"/>s.
/// </summary>
public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)HitObjectContainer;
[Resolved] [Resolved]
private IScrollingInfo scrollingInfo { get; set; } private IScrollingInfo scrollingInfo { get; set; }
@ -66,29 +21,8 @@ namespace osu.Game.Rulesets.UI.Scrolling
private void load() private void load()
{ {
Direction.BindTo(scrollingInfo.Direction); Direction.BindTo(scrollingInfo.Direction);
HitObjects.TimeRange.BindTo(VisibleTimeRange);
} }
public bool OnPressed(GlobalAction action)
{
if (!UserScrollSpeedAdjustment)
return false;
switch (action)
{
case GlobalAction.IncreaseScrollSpeed:
this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 200, Easing.OutQuint);
return true;
case GlobalAction.DecreaseScrollSpeed:
this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 200, Easing.OutQuint);
return true;
}
return false;
}
public bool OnReleased(GlobalAction action) => false;
protected sealed override HitObjectContainer CreateHitObjectContainer() => new ScrollingHitObjectContainer(); protected sealed override HitObjectContainer CreateHitObjectContainer() => new ScrollingHitObjectContainer();
} }
} }

View File

@ -5,10 +5,13 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Framework.Lists; using osu.Framework.Lists;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.Timing;
@ -20,14 +23,51 @@ namespace osu.Game.Rulesets.UI.Scrolling
/// A type of <see cref="RulesetContainer{TPlayfield,TObject}"/> that supports a <see cref="ScrollingPlayfield"/>. /// A type of <see cref="RulesetContainer{TPlayfield,TObject}"/> that supports a <see cref="ScrollingPlayfield"/>.
/// <see cref="HitObject"/>s inside this <see cref="RulesetContainer{TPlayfield,TObject}"/> will scroll within the playfield. /// <see cref="HitObject"/>s inside this <see cref="RulesetContainer{TPlayfield,TObject}"/> will scroll within the playfield.
/// </summary> /// </summary>
public abstract class ScrollingRulesetContainer<TPlayfield, TObject> : RulesetContainer<TPlayfield, TObject> public abstract class ScrollingRulesetContainer<TPlayfield, TObject> : RulesetContainer<TPlayfield, TObject>, IKeyBindingHandler<GlobalAction>
where TObject : HitObject where TObject : HitObject
where TPlayfield : ScrollingPlayfield where TPlayfield : ScrollingPlayfield
{ {
/// <summary>
/// The default span of time visible by the length of the scrolling axes.
/// This is clamped between <see cref="time_span_min"/> and <see cref="time_span_max"/>.
/// </summary>
private const double time_span_default = 1500;
/// <summary>
/// The minimum span of time that may be visible by the length of the scrolling axes.
/// </summary>
private const double time_span_min = 50;
/// <summary>
/// The maximum span of time that may be visible by the length of the scrolling axes.
/// </summary>
private const double time_span_max = 10000;
/// <summary>
/// The step increase/decrease of the span of time visible by the length of the scrolling axes.
/// </summary>
private const double time_span_step = 200;
protected readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>(); protected readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
/// <summary>
/// The span of time that is visible by the length of the scrolling axes.
/// For example, only hit objects with start time less than or equal to 1000 will be visible with <see cref="TimeRange"/> = 1000.
/// </summary>
protected readonly BindableDouble TimeRange = new BindableDouble(time_span_default)
{
Default = time_span_default,
MinValue = time_span_min,
MaxValue = time_span_max
};
protected virtual ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Sequential; protected virtual ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Sequential;
/// <summary>
/// Whether the player can change <see cref="VisibleTimeRange"/>.
/// </summary>
protected virtual bool UserScrollSpeedAdjustment => true;
/// <summary> /// <summary>
/// Provides the default <see cref="MultiplierControlPoint"/>s that adjust the scrolling rate of <see cref="HitObject"/>s /// Provides the default <see cref="MultiplierControlPoint"/>s that adjust the scrolling rate of <see cref="HitObject"/>s
/// inside this <see cref="RulesetContainer{TPlayfield,TObject}"/>. /// inside this <see cref="RulesetContainer{TPlayfield,TObject}"/>.
@ -45,6 +85,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
{ {
scrollingInfo = new LocalScrollingInfo(); scrollingInfo = new LocalScrollingInfo();
scrollingInfo.Direction.BindTo(Direction); scrollingInfo.Direction.BindTo(Direction);
scrollingInfo.TimeRange.BindTo(TimeRange);
switch (ScrollAlgorithm) switch (ScrollAlgorithm)
{ {
@ -108,10 +149,32 @@ namespace osu.Game.Rulesets.UI.Scrolling
controlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier }); controlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier });
} }
public bool OnPressed(GlobalAction action)
{
if (!UserScrollSpeedAdjustment)
return false;
switch (action)
{
case GlobalAction.IncreaseScrollSpeed:
this.TransformBindableTo(TimeRange, TimeRange - time_span_step, 200, Easing.OutQuint);
return true;
case GlobalAction.DecreaseScrollSpeed:
this.TransformBindableTo(TimeRange, TimeRange + time_span_step, 200, Easing.OutQuint);
return true;
}
return false;
}
public bool OnReleased(GlobalAction action) => false;
private class LocalScrollingInfo : IScrollingInfo private class LocalScrollingInfo : IScrollingInfo
{ {
public IBindable<ScrollingDirection> Direction { get; } = new Bindable<ScrollingDirection>(); public IBindable<ScrollingDirection> Direction { get; } = new Bindable<ScrollingDirection>();
public IBindable<double> TimeRange { get; } = new BindableDouble();
public IScrollAlgorithm Algorithm { get; set; } public IScrollAlgorithm Algorithm { get; set; }
} }
} }

View File

@ -22,6 +22,8 @@ namespace osu.Game.Tests.Visual
public ScrollAlgorithm ScrollAlgorithm { set => scrollingInfo.Algorithm.Algorithm = value; } public ScrollAlgorithm ScrollAlgorithm { set => scrollingInfo.Algorithm.Algorithm = value; }
public double TimeRange { set => scrollingInfo.TimeRange.Value = value; }
[Cached(Type = typeof(IScrollingInfo))] [Cached(Type = typeof(IScrollingInfo))]
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo(); private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
@ -37,6 +39,9 @@ namespace osu.Game.Tests.Visual
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>(); public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction; IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
public readonly Bindable<double> TimeRange = new Bindable<double>(1000) { Value = 1000 };
IBindable<double> IScrollingInfo.TimeRange => TimeRange;
public readonly TestScrollAlgorithm Algorithm = new TestScrollAlgorithm(); public readonly TestScrollAlgorithm Algorithm = new TestScrollAlgorithm();
IScrollAlgorithm IScrollingInfo.Algorithm => Algorithm; IScrollAlgorithm IScrollingInfo.Algorithm => Algorithm;
} }