1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-13 08:32:57 +08:00

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;
protected override bool UserScrollSpeedAdjustment => false;
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
{
Container explodingFruitContainer;
@ -50,8 +48,6 @@ namespace osu.Game.Rulesets.Catch.UI
HitObjectContainer
}
};
VisibleTimeRange.Value = BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
}
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 bool UserScrollSpeedAdjustment => false;
public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap)
{
Direction.Value = ScrollingDirection.Down;
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
}
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);

View File

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

View File

@ -123,7 +123,7 @@ namespace osu.Game.Rulesets.Mania.Tests
{
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);
return new ScrollingTestContainer(direction)
@ -132,6 +132,7 @@ namespace osu.Game.Rulesets.Mania.Tests
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
TimeRange = 2000,
Child = stage
};
}

View File

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

View File

@ -1,13 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// 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.Containers;
using System;
using System.Collections.Generic;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
@ -42,7 +40,6 @@ namespace osu.Game.Rulesets.Mania.UI
for (int i = 0; i < stageDefinitions.Count; i++)
{
var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
newStage.VisibleTimeRange.BindTo(VisibleTimeRange);
playfieldGrid.Content[0][i] = newStage;
@ -69,11 +66,5 @@ namespace osu.Game.Rulesets.Mania.UI
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);
configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true);
Config.BindWith(ManiaSetting.ScrollTime, TimeRange);
}
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)
{
c.VisibleTimeRange.BindTo(VisibleTimeRange);
topLevelContainer.Add(c.TopLevelContainer.CreateProxy());
columnFlow.Add(c);
AddNested(c);

View File

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

View File

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

View File

@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual
AddStep("Overlapping scroll", () => setScrollAlgorithm(ScrollAlgorithm.Overlapping));
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));
}

View File

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

View File

@ -12,14 +12,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
{
public class ScrollingHitObjectContainer : HitObjectContainer
{
/// <summary>
/// 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<double> timeRange = new BindableDouble();
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
@ -31,15 +24,16 @@ namespace osu.Game.Rulesets.UI.Scrolling
public ScrollingHitObjectContainer()
{
RelativeSizeAxes = Axes.Both;
TimeRange.ValueChanged += _ => initialStateCache.Invalidate();
direction.ValueChanged += _ => initialStateCache.Invalidate();
}
[BackgroundDependencyLoader]
private void load()
{
direction.BindTo(scrollingInfo.Direction);
timeRange.BindTo(scrollingInfo.TimeRange);
direction.ValueChanged += _ => initialStateCache.Invalidate();
timeRange.ValueChanged += _ => initialStateCache.Invalidate();
}
public override void Add(DrawableHitObject hitObject)
@ -93,7 +87,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
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)
{
@ -101,11 +95,11 @@ namespace osu.Game.Rulesets.UI.Scrolling
{
case ScrollingDirection.Up:
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;
case ScrollingDirection.Left:
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;
}
}
@ -133,16 +127,16 @@ namespace osu.Game.Rulesets.UI.Scrolling
switch (direction.Value)
{
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;
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;
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;
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;
}
}

View File

@ -3,9 +3,6 @@
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.UI.Scrolling
@ -13,52 +10,10 @@ namespace osu.Game.Rulesets.UI.Scrolling
/// <summary>
/// A type of <see cref="Playfield"/> specialized towards scrolling <see cref="DrawableHitObject"/>s.
/// </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>();
/// <summary>
/// The container that contains the <see cref="DrawableHitObject"/>s.
/// </summary>
public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)HitObjectContainer;
[Resolved]
private IScrollingInfo scrollingInfo { get; set; }
@ -66,29 +21,8 @@ namespace osu.Game.Rulesets.UI.Scrolling
private void load()
{
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();
}
}

View File

@ -5,10 +5,13 @@ using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Framework.Lists;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Configuration;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
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"/>.
/// <see cref="HitObject"/>s inside this <see cref="RulesetContainer{TPlayfield,TObject}"/> will scroll within the playfield.
/// </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 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>();
/// <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;
/// <summary>
/// Whether the player can change <see cref="VisibleTimeRange"/>.
/// </summary>
protected virtual bool UserScrollSpeedAdjustment => true;
/// <summary>
/// Provides the default <see cref="MultiplierControlPoint"/>s that adjust the scrolling rate of <see cref="HitObject"/>s
/// inside this <see cref="RulesetContainer{TPlayfield,TObject}"/>.
@ -45,6 +85,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
{
scrollingInfo = new LocalScrollingInfo();
scrollingInfo.Direction.BindTo(Direction);
scrollingInfo.TimeRange.BindTo(TimeRange);
switch (ScrollAlgorithm)
{
@ -108,10 +149,32 @@ namespace osu.Game.Rulesets.UI.Scrolling
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
{
public IBindable<ScrollingDirection> Direction { get; } = new Bindable<ScrollingDirection>();
public IBindable<double> TimeRange { get; } = new BindableDouble();
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 double TimeRange { set => scrollingInfo.TimeRange.Value = value; }
[Cached(Type = typeof(IScrollingInfo))]
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
@ -37,6 +39,9 @@ namespace osu.Game.Tests.Visual
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
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();
IScrollAlgorithm IScrollingInfo.Algorithm => Algorithm;
}