diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 102ec7fb3b..970dc2d630 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Judgements; @@ -24,6 +25,8 @@ namespace osu.Game.Rulesets.Catch.UI protected override bool UserScrollSpeedAdjustment => false; + protected override SpeedChangeVisualisationMethod VisualisationMethod => SpeedChangeVisualisationMethod.Constant; + public CatchPlayfield(BeatmapDifficulty difficulty, Func> getVisualRepresentation) : base(BASE_WIDTH) { @@ -55,6 +58,8 @@ namespace osu.Game.Rulesets.Catch.UI RelativeSizeAxes = Axes.Both, }, }); + + VisibleTimeRange.Value = BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450); } public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 325beb38a5..1219ccc0e8 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -1,23 +1,24 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // 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.Shapes; -using osu.Game.Rulesets.Taiko.Objects; -using OpenTK; -using OpenTK.Graphics; -using osu.Game.Rulesets.Taiko.Judgements; -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Extensions.Color4Extensions; using System.Linq; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Judgements; +using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Rulesets.Taiko.UI { @@ -40,6 +41,8 @@ namespace osu.Game.Rulesets.Taiko.UI protected override bool UserScrollSpeedAdjustment => false; + protected override SpeedChangeVisualisationMethod VisualisationMethod => SpeedChangeVisualisationMethod.Overlapping; + private readonly Container hitExplosionContainer; private readonly Container kiaiExplosionContainer; private readonly JudgementContainer judgementContainer; diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index f7fe424aa9..9ac2cabe9f 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -83,8 +83,6 @@ namespace osu.Game.Configuration Set(OsuSetting.ScoreDisplayMode, ScoringMode.Standardised); - Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential); - Set(OsuSetting.IncreaseFirstObjectVisibility, true); // Update @@ -143,7 +141,6 @@ namespace osu.Game.Configuration ChatDisplayHeight, Version, ShowConvertedBeatmaps, - SpeedChangeVisualisation, Skin, ScreenshotFormat, ScreenshotCaptureMenuCursor, diff --git a/osu.Game/Configuration/SpeedChangeVisualisationMethod.cs b/osu.Game/Configuration/SpeedChangeVisualisationMethod.cs index d38b1a89c5..39c6e5649c 100644 --- a/osu.Game/Configuration/SpeedChangeVisualisationMethod.cs +++ b/osu.Game/Configuration/SpeedChangeVisualisationMethod.cs @@ -10,6 +10,8 @@ namespace osu.Game.Configuration [Description("Sequential")] Sequential, [Description("Overlapping")] - Overlapping + Overlapping, + [Description("Constant")] + Constant } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs deleted file mode 100644 index 0e661aeba6..0000000000 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Game.Configuration; - -namespace osu.Game.Overlays.Settings.Sections.Gameplay -{ - public class ScrollingSettings : SettingsSubsection - { - protected override string Header => "Scrolling"; - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - Children = new[] - { - new SettingsEnumDropdown - { - LabelText = "Visualise speed changes as", - Bindable = config.GetBindable(OsuSetting.SpeedChangeVisualisation), - } - }; - } - } -} diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index 8add0b01ec..f565ff8556 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -21,7 +21,6 @@ namespace osu.Game.Overlays.Settings.Sections { new GeneralSettings(), new SongSelectSettings(), - new ScrollingSettings(), new ModsSettings(), }; } @@ -29,7 +28,7 @@ namespace osu.Game.Overlays.Settings.Sections [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - foreach(Ruleset ruleset in rulesets.AvailableRulesets.Select(info => info.CreateInstance())) + foreach (Ruleset ruleset in rulesets.AvailableRulesets.Select(info => info.CreateInstance())) { SettingsSubsection section = ruleset.CreateSettings(); if (section != null) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index df9370d0d8..254de6c6f7 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -102,7 +102,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics } else resolutionDropdown.Hide(); - }); + }, true); } letterboxing.BindValueChanged(isVisible => diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index c64fca6eff..7307fc0ead 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -33,20 +32,16 @@ namespace osu.Game.Rulesets.UI.Scrolling private Cached initialStateCache = new Cached(); - public ScrollingHitObjectContainer() + private readonly ISpeedChangeVisualiser speedChangeVisualiser; + + public ScrollingHitObjectContainer(SpeedChangeVisualisationMethod visualisationMethod) { RelativeSizeAxes = Axes.Both; TimeRange.ValueChanged += _ => initialStateCache.Invalidate(); Direction.ValueChanged += _ => initialStateCache.Invalidate(); - } - private ISpeedChangeVisualiser speedChangeVisualiser; - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - switch (config.Get(OsuSetting.SpeedChangeVisualisation)) + switch (visualisationMethod) { case SpeedChangeVisualisationMethod.Sequential: speedChangeVisualiser = new SequentialSpeedChangeVisualiser(ControlPoints); @@ -54,6 +49,9 @@ namespace osu.Game.Rulesets.UI.Scrolling case SpeedChangeVisualisationMethod.Overlapping: speedChangeVisualiser = new OverlappingSpeedChangeVisualiser(ControlPoints); break; + case SpeedChangeVisualisationMethod.Constant: + speedChangeVisualiser = new ConstantSpeedChangeVisualiser(); + break; } } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index ec73c0fb14..b85531909c 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; +using osu.Game.Configuration; using osu.Game.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; @@ -62,6 +63,8 @@ namespace osu.Game.Rulesets.UI.Scrolling /// protected readonly Bindable Direction = new Bindable(); + protected virtual SpeedChangeVisualisationMethod VisualisationMethod => SpeedChangeVisualisationMethod.Sequential; + /// /// Creates a new . /// @@ -104,7 +107,7 @@ namespace osu.Game.Rulesets.UI.Scrolling protected sealed override HitObjectContainer CreateHitObjectContainer() { - var container = new ScrollingHitObjectContainer(); + var container = new ScrollingHitObjectContainer(VisualisationMethod); container.Direction.BindTo(Direction); return container; } diff --git a/osu.Game/Rulesets/UI/Scrolling/Visualisers/ConstantSpeedChangeVisualiser.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/ConstantSpeedChangeVisualiser.cs new file mode 100644 index 0000000000..9e910d6b11 --- /dev/null +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/ConstantSpeedChangeVisualiser.cs @@ -0,0 +1,67 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +using OpenTK; + +namespace osu.Game.Rulesets.UI.Scrolling.Visualisers +{ + public class ConstantSpeedChangeVisualiser : ISpeedChangeVisualiser + { + public void ComputeInitialStates(IEnumerable hitObjects, ScrollingDirection direction, double timeRange, Vector2 length) + { + foreach (var obj in hitObjects) + { + obj.LifetimeStart = obj.HitObject.StartTime - timeRange; + + if (obj.HitObject is IHasEndTime endTime) + { + var hitObjectLength = (endTime.EndTime - obj.HitObject.StartTime) / timeRange; + + switch (direction) + { + case ScrollingDirection.Up: + case ScrollingDirection.Down: + obj.Height = (float)(hitObjectLength * length.Y); + break; + case ScrollingDirection.Left: + case ScrollingDirection.Right: + obj.Width = (float)(hitObjectLength * length.X); + break; + } + } + + ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); + + // Nested hitobjects don't need to scroll, but they do need accurate positions + UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); + } + } + + public void UpdatePositions(IEnumerable hitObjects, ScrollingDirection direction, double currentTime, double timeRange, Vector2 length) + { + foreach (var obj in hitObjects) + { + var position = (obj.HitObject.StartTime - currentTime) / timeRange; + + switch (direction) + { + case ScrollingDirection.Up: + obj.Y = (float)(position * length.Y); + break; + case ScrollingDirection.Down: + obj.Y = (float)(-position * length.Y); + break; + case ScrollingDirection.Left: + obj.X = (float)(position * length.X); + break; + case ScrollingDirection.Right: + obj.X = (float)(-position * length.X); + break; + } + } + } + } +}