1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 17:07:38 +08:00

Merge branch 'master' into custom-storage-startup-exception

This commit is contained in:
smoogipoo 2020-07-06 20:04:18 +09:00
commit 09d45ea47a
22 changed files with 75 additions and 71 deletions

View File

@ -8,7 +8,6 @@ using NUnit.Framework;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.Mods;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Beatmaps;
@ -83,7 +82,7 @@ namespace osu.Game.Rulesets.Catch.Tests
public float Position public float Position
{ {
get => HitObject?.X * CatchPlayfield.BASE_WIDTH ?? position; get => HitObject?.X ?? position;
set => position = value; set => position = value;
} }

View File

@ -27,15 +27,15 @@ namespace osu.Game.Rulesets.Catch.Tests
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {
float width = (i % 10 + 1) / 20f; float width = (i % 10 + 1) / 20f * CatchPlayfield.WIDTH;
beatmap.HitObjects.Add(new JuiceStream beatmap.HitObjects.Add(new JuiceStream
{ {
X = 0.5f - width / 2, X = CatchPlayfield.CENTER_X - width / 2,
Path = new SliderPath(PathType.Linear, new[] Path = new SliderPath(PathType.Linear, new[]
{ {
Vector2.Zero, Vector2.Zero,
new Vector2(width * CatchPlayfield.BASE_WIDTH, 0) new Vector2(width, 0)
}), }),
StartTime = i * 2000, StartTime = i * 2000,
NewCombo = i % 8 == 0 NewCombo = i % 8 == 0

View File

@ -4,6 +4,7 @@
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
namespace osu.Game.Rulesets.Catch.Tests namespace osu.Game.Rulesets.Catch.Tests
{ {
@ -22,7 +23,14 @@ namespace osu.Game.Rulesets.Catch.Tests
}; };
for (int i = 0; i < 512; i++) for (int i = 0; i < 512; i++)
beatmap.HitObjects.Add(new Fruit { X = 0.5f + i / 2048f * (i % 10 - 5), StartTime = i * 100, NewCombo = i % 8 == 0 }); {
beatmap.HitObjects.Add(new Fruit
{
X = (0.5f + i / 2048f * (i % 10 - 5)) * CatchPlayfield.WIDTH,
StartTime = i * 100,
NewCombo = i % 8 == 0
});
}
return beatmap; return beatmap;
} }

View File

@ -76,8 +76,8 @@ namespace osu.Game.Rulesets.Catch.Tests
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size }) Child = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size })
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.Centre,
Origin = Anchor.TopLeft, Origin = Anchor.TopCentre,
CreateDrawableRepresentation = ((DrawableRuleset<CatchHitObject>)catchRuleset.CreateInstance().CreateDrawableRulesetWith(new CatchBeatmap())).CreateDrawableRepresentation CreateDrawableRepresentation = ((DrawableRuleset<CatchHitObject>)catchRuleset.CreateInstance().CreateDrawableRulesetWith(new CatchBeatmap())).CreateDrawableRepresentation
}, },
}); });

View File

@ -158,8 +158,8 @@ namespace osu.Game.Rulesets.Catch.Tests
private float getXCoords(bool hit) private float getXCoords(bool hit)
{ {
const float x_offset = 0.2f; const float x_offset = 0.2f * CatchPlayfield.WIDTH;
float xCoords = drawableRuleset.Playfield.Width / 2; float xCoords = CatchPlayfield.CENTER_X;
if (drawableRuleset.Playfield is CatchPlayfield catchPlayfield) if (drawableRuleset.Playfield is CatchPlayfield catchPlayfield)
catchPlayfield.CatcherArea.MovableCatcher.X = xCoords - x_offset; catchPlayfield.CatcherArea.MovableCatcher.X = xCoords - x_offset;

View File

@ -47,13 +47,13 @@ namespace osu.Game.Rulesets.Catch.Tests
}; };
// Should produce a hyper-dash (edge case test) // Should produce a hyper-dash (edge case test)
beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56 / 512f, NewCombo = true }); beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true });
beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308 / 512f, NewCombo = true }); beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true });
double startTime = 3000; double startTime = 3000;
const float left_x = 0.02f; const float left_x = 0.02f * CatchPlayfield.WIDTH;
const float right_x = 0.98f; const float right_x = 0.98f * CatchPlayfield.WIDTH;
createObjects(() => new Fruit { X = left_x }); createObjects(() => new Fruit { X = left_x });
createObjects(() => new TestJuiceStream(right_x), 1); createObjects(() => new TestJuiceStream(right_x), 1);

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osuTK; using osuTK;
@ -30,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Tests
{ {
new JuiceStream new JuiceStream
{ {
X = 0.5f, X = CatchPlayfield.CENTER_X,
Path = new SliderPath(PathType.Linear, new[] Path = new SliderPath(PathType.Linear, new[]
{ {
Vector2.Zero, Vector2.Zero,
@ -40,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Tests
}, },
new Banana new Banana
{ {
X = 0.5f, X = CatchPlayfield.CENTER_X,
StartTime = 1000, StartTime = 1000,
NewCombo = true NewCombo = true
} }

View File

@ -5,7 +5,6 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
@ -36,7 +35,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
Path = curveData.Path, Path = curveData.Path,
NodeSamples = curveData.NodeSamples, NodeSamples = curveData.NodeSamples,
RepeatCount = curveData.RepeatCount, RepeatCount = curveData.RepeatCount,
X = (positionData?.X ?? 0) / CatchPlayfield.BASE_WIDTH, X = positionData?.X ?? 0,
NewCombo = comboData?.NewCombo ?? false, NewCombo = comboData?.NewCombo ?? false,
ComboOffset = comboData?.ComboOffset ?? 0, ComboOffset = comboData?.ComboOffset ?? 0,
LegacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0 LegacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0
@ -59,7 +58,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
Samples = obj.Samples, Samples = obj.Samples,
NewCombo = comboData?.NewCombo ?? false, NewCombo = comboData?.NewCombo ?? false,
ComboOffset = comboData?.ComboOffset ?? 0, ComboOffset = comboData?.ComboOffset ?? 0,
X = (positionData?.X ?? 0) / CatchPlayfield.BASE_WIDTH X = positionData?.X ?? 0
}.Yield(); }.Yield();
} }
} }

View File

@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
case BananaShower bananaShower: case BananaShower bananaShower:
foreach (var banana in bananaShower.NestedHitObjects.OfType<Banana>()) foreach (var banana in bananaShower.NestedHitObjects.OfType<Banana>())
{ {
banana.XOffset = (float)rng.NextDouble(); banana.XOffset = (float)(rng.NextDouble() * CatchPlayfield.WIDTH);
rng.Next(); // osu!stable retrieved a random banana type rng.Next(); // osu!stable retrieved a random banana type
rng.Next(); // osu!stable retrieved a random banana rotation rng.Next(); // osu!stable retrieved a random banana rotation
rng.Next(); // osu!stable retrieved a random banana colour rng.Next(); // osu!stable retrieved a random banana colour
@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
case JuiceStream juiceStream: case JuiceStream juiceStream:
// Todo: BUG!! Stable used the last control point as the final position of the path, but it should use the computed path instead. // Todo: BUG!! Stable used the last control point as the final position of the path, but it should use the computed path instead.
lastPosition = juiceStream.X + juiceStream.Path.ControlPoints[^1].Position.Value.X / CatchPlayfield.BASE_WIDTH; lastPosition = juiceStream.X + juiceStream.Path.ControlPoints[^1].Position.Value.X;
// Todo: BUG!! Stable attempted to use the end time of the stream, but referenced it too early in execution and used the start time instead. // Todo: BUG!! Stable attempted to use the end time of the stream, but referenced it too early in execution and used the start time instead.
lastStartTime = juiceStream.StartTime; lastStartTime = juiceStream.StartTime;
@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
catchObject.XOffset = 0; catchObject.XOffset = 0;
if (catchObject is TinyDroplet) if (catchObject is TinyDroplet)
catchObject.XOffset = Math.Clamp(rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH, -catchObject.X, 1 - catchObject.X); catchObject.XOffset = Math.Clamp(rng.Next(-20, 20), -catchObject.X, CatchPlayfield.WIDTH - catchObject.X);
else if (catchObject is Droplet) else if (catchObject is Droplet)
rng.Next(); // osu!stable retrieved a random droplet rotation rng.Next(); // osu!stable retrieved a random droplet rotation
} }
@ -131,7 +131,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
} }
// ReSharper disable once PossibleLossOfFraction // ReSharper disable once PossibleLossOfFraction
if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3) if (Math.Abs(positionDiff) < timeDiff / 3)
applyOffset(ref offsetPosition, positionDiff); applyOffset(ref offsetPosition, positionDiff);
hitObject.XOffset = offsetPosition - hitObject.X; hitObject.XOffset = offsetPosition - hitObject.X;
@ -149,12 +149,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
private static void applyRandomOffset(ref float position, double maxOffset, FastRandom rng) private static void applyRandomOffset(ref float position, double maxOffset, FastRandom rng)
{ {
bool right = rng.NextBool(); bool right = rng.NextBool();
float rand = Math.Min(20, (float)rng.Next(0, Math.Max(0, maxOffset))) / CatchPlayfield.BASE_WIDTH; float rand = Math.Min(20, (float)rng.Next(0, Math.Max(0, maxOffset)));
if (right) if (right)
{ {
// Clamp to the right bound // Clamp to the right bound
if (position + rand <= 1) if (position + rand <= CatchPlayfield.WIDTH)
position += rand; position += rand;
else else
position -= rand; position -= rand;
@ -211,7 +211,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
objectWithDroplets.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime)); objectWithDroplets.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime));
double halfCatcherWidth = CatcherArea.GetCatcherSize(beatmap.BeatmapInfo.BaseDifficulty) / 2; double halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.BeatmapInfo.BaseDifficulty) / 2;
int lastDirection = 0; int lastDirection = 0;
double lastExcess = halfCatcherWidth; double lastExcess = halfCatcherWidth;

View File

@ -3,7 +3,6 @@
using System; using System;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
@ -33,8 +32,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
// We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps. // We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps.
var scalingFactor = normalized_hitobject_radius / halfCatcherWidth; var scalingFactor = normalized_hitobject_radius / halfCatcherWidth;
NormalizedPosition = BaseObject.X * CatchPlayfield.BASE_WIDTH * scalingFactor; NormalizedPosition = BaseObject.X * scalingFactor;
LastNormalizedPosition = LastObject.X * CatchPlayfield.BASE_WIDTH * scalingFactor; LastNormalizedPosition = LastObject.X * scalingFactor;
// Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure // Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure
StrainTime = Math.Max(40, DeltaTime); StrainTime = Math.Max(40, DeltaTime);

View File

@ -3,7 +3,6 @@
using System; using System;
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing; using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Difficulty.Skills;
@ -68,7 +67,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
} }
// Bonus for edge dashes. // Bonus for edge dashes.
if (catchCurrent.LastObject.DistanceToHyperDash <= 20.0f / CatchPlayfield.BASE_WIDTH) if (catchCurrent.LastObject.DistanceToHyperDash <= 20.0f)
{ {
if (!catchCurrent.LastObject.HyperDash) if (!catchCurrent.LastObject.HyperDash)
edgeDashBonus += 5.7; edgeDashBonus += 5.7;
@ -78,7 +77,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
playerPosition = catchCurrent.NormalizedPosition; playerPosition = catchCurrent.NormalizedPosition;
} }
distanceAddition *= 1.0 + edgeDashBonus * ((20 - catchCurrent.LastObject.DistanceToHyperDash * CatchPlayfield.BASE_WIDTH) / 20) * Math.Pow((Math.Min(catchCurrent.StrainTime * catchCurrent.ClockRate, 265) / 265), 1.5); // Edge Dashes are easier at lower ms values distanceAddition *= 1.0 + edgeDashBonus * ((20 - catchCurrent.LastObject.DistanceToHyperDash) / 20) * Math.Pow((Math.Min(catchCurrent.StrainTime * catchCurrent.ClockRate, 265) / 265), 1.5); // Edge Dashes are easier at lower ms values
} }
lastPlayerPosition = playerPosition; lastPlayerPosition = playerPosition;

View File

@ -5,6 +5,7 @@ using osu.Framework.Bindables;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.UI;
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.Scoring; using osu.Game.Rulesets.Scoring;
@ -17,6 +18,9 @@ namespace osu.Game.Rulesets.Catch.Objects
private float x; private float x;
/// <summary>
/// The horizontal position of the fruit between 0 and <see cref="CatchPlayfield.WIDTH"/>.
/// </summary>
public float X public float X
{ {
get => x + XOffset; get => x + XOffset;

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Catch.UI;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -70,12 +71,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale; public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale;
protected override float SamplePlaybackPosition => HitObject.X; protected override float SamplePlaybackPosition => HitObject.X / CatchPlayfield.WIDTH;
protected DrawableCatchHitObject(CatchHitObject hitObject) protected DrawableCatchHitObject(CatchHitObject hitObject)
: base(hitObject) : base(hitObject)
{ {
RelativePositionAxes = Axes.X;
X = hitObject.X; X = hitObject.X;
} }

View File

@ -7,7 +7,6 @@ using System.Threading;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
@ -80,7 +79,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{ {
StartTime = t + lastEvent.Value.Time, StartTime = t + lastEvent.Value.Time,
X = X + Path.PositionAt( X = X + Path.PositionAt(
lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X / CatchPlayfield.BASE_WIDTH, lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X,
}); });
} }
} }
@ -97,7 +96,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{ {
Samples = dropletSamples, Samples = dropletSamples,
StartTime = e.Time, StartTime = e.Time,
X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH, X = X + Path.PositionAt(e.PathProgress).X,
}); });
break; break;
@ -108,14 +107,14 @@ namespace osu.Game.Rulesets.Catch.Objects
{ {
Samples = Samples, Samples = Samples,
StartTime = e.Time, StartTime = e.Time,
X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH, X = X + Path.PositionAt(e.PathProgress).X,
}); });
break; break;
} }
} }
} }
public float EndX => X + this.CurvePositionAt(1).X / CatchPlayfield.BASE_WIDTH; public float EndX => X + this.CurvePositionAt(1).X;
public double Duration public double Duration
{ {

View File

@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Catch.Replays
// todo: add support for HT DT // todo: add support for HT DT
const double dash_speed = Catcher.BASE_SPEED; const double dash_speed = Catcher.BASE_SPEED;
const double movement_speed = dash_speed / 2; const double movement_speed = dash_speed / 2;
float lastPosition = 0.5f; float lastPosition = CatchPlayfield.CENTER_X;
double lastTime = 0; double lastTime = 0;
void moveToNext(CatchHitObject h) void moveToNext(CatchHitObject h)
@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.Replays
bool impossibleJump = speedRequired > movement_speed * 2; bool impossibleJump = speedRequired > movement_speed * 2;
// todo: get correct catcher size, based on difficulty CS. // todo: get correct catcher size, based on difficulty CS.
const float catcher_width_half = CatcherArea.CATCHER_SIZE / CatchPlayfield.BASE_WIDTH * 0.3f * 0.5f; const float catcher_width_half = CatcherArea.CATCHER_SIZE * 0.3f * 0.5f;
if (lastPosition - catcher_width_half < h.X && lastPosition + catcher_width_half > h.X) if (lastPosition - catcher_width_half < h.X && lastPosition + catcher_width_half > h.X)
{ {

View File

@ -4,7 +4,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Replays.Legacy; using osu.Game.Replays.Legacy;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Replays.Types;
@ -41,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Replays
public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayFrame lastFrame = null) public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayFrame lastFrame = null)
{ {
Position = currentFrame.Position.X / CatchPlayfield.BASE_WIDTH; Position = currentFrame.Position.X;
Dashing = currentFrame.ButtonState == ReplayButtonState.Left1; Dashing = currentFrame.ButtonState == ReplayButtonState.Left1;
if (Dashing) if (Dashing)
@ -63,7 +62,7 @@ namespace osu.Game.Rulesets.Catch.Replays
if (Actions.Contains(CatchAction.Dash)) state |= ReplayButtonState.Left1; if (Actions.Contains(CatchAction.Dash)) state |= ReplayButtonState.Left1;
return new LegacyReplayFrame(Time, Position * CatchPlayfield.BASE_WIDTH, null, state); return new LegacyReplayFrame(Time, Position, null, state);
} }
} }
} }

View File

@ -16,7 +16,16 @@ namespace osu.Game.Rulesets.Catch.UI
{ {
public class CatchPlayfield : ScrollingPlayfield public class CatchPlayfield : ScrollingPlayfield
{ {
public const float BASE_WIDTH = 512; /// <summary>
/// The width of the playfield.
/// The horizontal movement of the catcher is confined in the area of this width.
/// </summary>
public const float WIDTH = 512;
/// <summary>
/// The center position of the playfield.
/// </summary>
public const float CENTER_X = WIDTH / 2;
internal readonly CatcherArea CatcherArea; internal readonly CatcherArea CatcherArea;

View File

@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.UI
{ {
base.Update(); base.Update();
Scale = new Vector2(Parent.ChildSize.X / CatchPlayfield.BASE_WIDTH); Scale = new Vector2(Parent.ChildSize.X / CatchPlayfield.WIDTH);
Size = Vector2.Divide(Vector2.One, Scale); Size = Vector2.Divide(Vector2.One, Scale);
} }
} }

View File

@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Catch.UI
/// <summary> /// <summary>
/// The relative space to cover in 1 millisecond. based on 1 game pixel per millisecond as in osu-stable. /// The relative space to cover in 1 millisecond. based on 1 game pixel per millisecond as in osu-stable.
/// </summary> /// </summary>
public const double BASE_SPEED = 1.0 / 512; public const double BASE_SPEED = 1.0;
public Container ExplodingFruitTarget; public Container ExplodingFruitTarget;
@ -104,9 +104,6 @@ namespace osu.Game.Rulesets.Catch.UI
{ {
this.trailsTarget = trailsTarget; this.trailsTarget = trailsTarget;
RelativePositionAxes = Axes.X;
X = 0.5f;
Origin = Anchor.TopCentre; Origin = Anchor.TopCentre;
Size = new Vector2(CatcherArea.CATCHER_SIZE); Size = new Vector2(CatcherArea.CATCHER_SIZE);
@ -209,8 +206,8 @@ namespace osu.Game.Rulesets.Catch.UI
var halfCatchWidth = catchWidth * 0.5f; var halfCatchWidth = catchWidth * 0.5f;
// this stuff wil disappear once we move fruit to non-relative coordinate space in the future. // this stuff wil disappear once we move fruit to non-relative coordinate space in the future.
var catchObjectPosition = fruit.X * CatchPlayfield.BASE_WIDTH; var catchObjectPosition = fruit.X;
var catcherPosition = Position.X * CatchPlayfield.BASE_WIDTH; var catcherPosition = Position.X;
var validCatch = var validCatch =
catchObjectPosition >= catcherPosition - halfCatchWidth && catchObjectPosition >= catcherPosition - halfCatchWidth &&
@ -224,7 +221,7 @@ namespace osu.Game.Rulesets.Catch.UI
{ {
var target = fruit.HyperDashTarget; var target = fruit.HyperDashTarget;
var timeDifference = target.StartTime - fruit.StartTime; var timeDifference = target.StartTime - fruit.StartTime;
double positionDifference = target.X * CatchPlayfield.BASE_WIDTH - catcherPosition; double positionDifference = target.X - catcherPosition;
var velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0); var velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
SetHyperDashState(Math.Abs(velocity), target.X); SetHyperDashState(Math.Abs(velocity), target.X);
@ -331,7 +328,7 @@ namespace osu.Game.Rulesets.Catch.UI
public void UpdatePosition(float position) public void UpdatePosition(float position)
{ {
position = Math.Clamp(position, 0, 1); position = Math.Clamp(position, 0, CatchPlayfield.WIDTH);
if (position == X) if (position == X)
return; return;

View File

@ -31,14 +31,8 @@ namespace osu.Game.Rulesets.Catch.UI
public CatcherArea(BeatmapDifficulty difficulty = null) public CatcherArea(BeatmapDifficulty difficulty = null)
{ {
RelativeSizeAxes = Axes.X; Size = new Vector2(CatchPlayfield.WIDTH, CATCHER_SIZE);
Height = CATCHER_SIZE; Child = MovableCatcher = new Catcher(this, difficulty) { X = CatchPlayfield.CENTER_X };
Child = MovableCatcher = new Catcher(this, difficulty);
}
public static float GetCatcherSize(BeatmapDifficulty difficulty)
{
return CATCHER_SIZE / CatchPlayfield.BASE_WIDTH * (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5);
} }
public void OnResult(DrawableCatchHitObject fruit, JudgementResult result) public void OnResult(DrawableCatchHitObject fruit, JudgementResult result)

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Audio.Track;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Screens.Menu; using osu.Game.Screens.Menu;
@ -14,15 +15,11 @@ namespace osu.Game.Tests.Visual.Menus
public TestSceneIntroWelcome() public TestSceneIntroWelcome()
{ {
AddAssert("check if menu music loops", () => AddUntilStep("wait for load", () => getTrack() != null);
{
var menu = IntroStack?.CurrentScreen as MainMenu;
if (menu == null) AddAssert("check if menu music loops", () => getTrack().Looping);
return false;
return menu.Track.Looping;
});
} }
private Track getTrack() => (IntroStack?.CurrentScreen as MainMenu)?.Track;
} }
} }

View File

@ -218,7 +218,7 @@ namespace osu.Game.Beatmaps.Formats
break; break;
case 2: case 2:
position.X = ((IHasXPosition)hitObject).X * 512; position.X = ((IHasXPosition)hitObject).X;
break; break;
case 3: case 3: