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

Simplify flow of progression to be linear

This commit is contained in:
Dean Herbert 2022-06-10 15:19:10 +09:00
parent 5541ebc76b
commit e0644f2726
2 changed files with 142 additions and 96 deletions

View File

@ -29,22 +29,46 @@ namespace osu.Game.Tests.Visual.Settings
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
clickCorrectUntilResults(); int difficulty = i + 1;
AddAssert("check at results", () => !latencyCertifier.ChildrenOfType<LatencyArea>().Any());
AddStep("hit c to continue", () => InputManager.Key(Key.C)); checkDifficulty(difficulty);
clickUntilResults(true);
continueFromResults();
} }
checkDifficulty(5);
clickUntilResults(false);
continueFromResults();
checkDifficulty(4);
clickUntilResults(false);
continueFromResults();
checkDifficulty(3);
clickUntilResults(true);
AddAssert("check at results", () => !latencyCertifier.ChildrenOfType<LatencyArea>().Any()); AddAssert("check at results", () => !latencyCertifier.ChildrenOfType<LatencyArea>().Any());
AddAssert("check no buttons", () => !latencyCertifier.ChildrenOfType<OsuButton>().Any()); AddAssert("check no buttons", () => !latencyCertifier.ChildrenOfType<OsuButton>().Any());
checkDifficulty(3);
} }
private void clickCorrectUntilResults() private void continueFromResults()
{
AddAssert("check at results", () => !latencyCertifier.ChildrenOfType<LatencyArea>().Any());
AddStep("hit enter to continue", () => InputManager.Key(Key.Enter));
}
private void checkDifficulty(int difficulty)
{
AddAssert($"difficulty is {difficulty}", () => latencyCertifier.DifficultyLevel == difficulty);
}
private void clickUntilResults(bool clickCorrect)
{ {
AddUntilStep("click correct button until results", () => AddUntilStep("click correct button until results", () =>
{ {
var latencyArea = latencyCertifier var latencyArea = latencyCertifier
.ChildrenOfType<LatencyArea>() .ChildrenOfType<LatencyArea>()
.SingleOrDefault(a => a.TargetFrameRate == null); .SingleOrDefault(a => clickCorrect ? a.TargetFrameRate == null : a.TargetFrameRate != null);
// reached results // reached results
if (latencyArea == null) if (latencyArea == null)

View File

@ -66,11 +66,17 @@ namespace osu.Game.Screens.Utility
private const int rounds_to_complete_certified = 20; private const int rounds_to_complete_certified = 20;
/// <summary>
/// Whether we are now in certification mode and decreasing difficulty.
/// </summary>
private bool isCertifying;
private int totalRoundForNextResultsScreen => isCertifying ? rounds_to_complete_certified : rounds_to_complete;
private int attemptsAtCurrentDifficulty; private int attemptsAtCurrentDifficulty;
private int correctAtCurrentDifficulty; private int correctAtCurrentDifficulty;
private int totalRoundForNextResultsScreen = rounds_to_complete;
private int difficultyLevel = 1; public int DifficultyLevel { get; private set; } = 1;
private double lastPoll; private double lastPoll;
private int pollingMax; private int pollingMax;
@ -199,11 +205,11 @@ Do whatever you need to try and perceive the difference in latency, then choose
statusText.Clear(); statusText.Clear();
float successRate = (float)correctAtCurrentDifficulty / totalRoundForNextResultsScreen; float successRate = (float)correctAtCurrentDifficulty / attemptsAtCurrentDifficulty;
bool isPass = successRate == 1; bool isPass = successRate == 1;
statusText.AddParagraph($"You scored {correctAtCurrentDifficulty} out of {totalRoundForNextResultsScreen} ({successRate:0%})!", cp => cp.Colour = isPass ? colours.Green : colours.Red); statusText.AddParagraph($"You scored {correctAtCurrentDifficulty} out of {attemptsAtCurrentDifficulty} ({successRate:0%})!", cp => cp.Colour = isPass ? colours.Green : colours.Red);
statusText.AddParagraph($"Level {difficultyLevel} ({mapDifficultyToTargetFrameRate(difficultyLevel):N0} Hz)", statusText.AddParagraph($"Level {DifficultyLevel} ({mapDifficultyToTargetFrameRate(DifficultyLevel):N0} Hz)",
cp => cp.Font = OsuFont.Default.With(size: 24)); cp => cp.Font = OsuFont.Default.With(size: 24));
statusText.AddParagraph(string.Empty); statusText.AddParagraph(string.Empty);
@ -211,9 +217,9 @@ Do whatever you need to try and perceive the difference in latency, then choose
statusText.AddIcon(isPass ? FontAwesome.Regular.CheckCircle : FontAwesome.Regular.TimesCircle, cp => cp.Colour = isPass ? colours.Green : colours.Red); statusText.AddIcon(isPass ? FontAwesome.Regular.CheckCircle : FontAwesome.Regular.TimesCircle, cp => cp.Colour = isPass ? colours.Green : colours.Red);
statusText.AddParagraph(string.Empty); statusText.AddParagraph(string.Empty);
if (!isPass && difficultyLevel > 1) if (!isPass && DifficultyLevel > 1)
{ {
statusText.AddParagraph("To complete certification, decrease the difficulty level until you can get 20 tests correct in a row!", statusText.AddParagraph("To complete certification, the difficulty level will now decrease until you can get 20 rounds correct in a row!",
cp => cp.Font = OsuFont.Default.With(size: 24, weight: FontWeight.SemiBold)); cp => cp.Font = OsuFont.Default.With(size: 24, weight: FontWeight.SemiBold));
statusText.AddParagraph(string.Empty); statusText.AddParagraph(string.Empty);
} }
@ -226,67 +232,22 @@ Do whatever you need to try and perceive the difference in latency, then choose
+ $"Draw: {host.DrawThread.Clock.FramesPerSecond} Hz" + $"Draw: {host.DrawThread.Clock.FramesPerSecond} Hz"
, cp => cp.Font = OsuFont.Default.With(size: 15, weight: FontWeight.SemiBold)); , cp => cp.Font = OsuFont.Default.With(size: 15, weight: FontWeight.SemiBold));
int certificationRemaining = !isPass ? rounds_to_complete_certified : rounds_to_complete_certified - correctAtCurrentDifficulty; if (isCertifying && isPass)
if (isPass && certificationRemaining <= 0)
{ {
Drawable background; showCertifiedScreen();
Drawable certifiedText;
resultsArea.AddRange(new[]
{
background = new Box
{
Colour = overlayColourProvider.Background4,
RelativeSizeAxes = Axes.Both,
},
(certifiedText = new OsuSpriteText
{
Alpha = 0,
Font = OsuFont.TorusAlternate.With(size: 80, weight: FontWeight.Bold),
Text = "Certified!",
Blending = BlendingParameters.Additive,
}).WithEffect(new GlowEffect
{
Colour = overlayColourProvider.Colour1,
PadExtent = true
}).With(e =>
{
e.Anchor = Anchor.Centre;
e.Origin = Anchor.Centre;
}),
new OsuSpriteText
{
Text = $"You should use a frame limiter with update rate of {mapDifficultyToTargetFrameRate(difficultyLevel + 1)} Hz (or fps) for best results!",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.Torus.With(size: 24, weight: FontWeight.SemiBold),
Y = 80,
}
});
background.FadeInFromZero(1000, Easing.OutQuint);
certifiedText.FadeInFromZero(500, Easing.InQuint);
certifiedText
.ScaleTo(10)
.ScaleTo(1, 600, Easing.InQuad)
.Then()
.ScaleTo(1.05f, 10000, Easing.OutQuint);
return; return;
} }
string cannotIncreaseReason = string.Empty; string cannotIncreaseReason = string.Empty;
if (!isPass) if (mapDifficultyToTargetFrameRate(DifficultyLevel + 1) > target_host_update_frames)
cannotIncreaseReason = "You didn't get a perfect score.";
else if (mapDifficultyToTargetFrameRate(difficultyLevel + 1) > target_host_update_frames)
cannotIncreaseReason = "You've reached the maximum level."; cannotIncreaseReason = "You've reached the maximum level.";
else if (mapDifficultyToTargetFrameRate(difficultyLevel + 1) > Clock.FramesPerSecond) else if (mapDifficultyToTargetFrameRate(DifficultyLevel + 1) > Clock.FramesPerSecond)
cannotIncreaseReason = "Game is not running fast enough to test this level"; cannotIncreaseReason = "Game is not running fast enough to test this level";
resultsArea.Add(new FillFlowContainer FillFlowContainer buttonFlow;
resultsArea.Add(buttonFlow = new FillFlowContainer
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
@ -294,42 +255,104 @@ Do whatever you need to try and perceive the difference in latency, then choose
Origin = Anchor.BottomLeft, Origin = Anchor.BottomLeft,
Spacing = new Vector2(20), Spacing = new Vector2(20),
Padding = new MarginPadding(20), Padding = new MarginPadding(20),
Children = new Drawable[] });
if (isPass)
{
buttonFlow.Add(new ButtonWithKeyBind(Key.Enter)
{ {
new ButtonWithKeyBind(Key.Enter) Text = "Continue to next level",
BackgroundColour = colours.Green,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = () => changeDifficulty(DifficultyLevel + 1),
Enabled = { Value = string.IsNullOrEmpty(cannotIncreaseReason) },
TooltipText = cannotIncreaseReason
});
}
else
{
if (DifficultyLevel == 1)
{
buttonFlow.Add(new ButtonWithKeyBind(Key.Enter)
{ {
Text = "Continue to next level", Text = "Retry",
BackgroundColour = colours.Red2, TooltipText = "Are you even trying..?",
Anchor = Anchor.Centre, BackgroundColour = colours.Pink2,
Origin = Anchor.Centre,
Action = () => changeDifficulty(difficultyLevel + 1),
Enabled = { Value = string.IsNullOrEmpty(cannotIncreaseReason) },
TooltipText = cannotIncreaseReason
},
new ButtonWithKeyBind(Key.D)
{
Text = difficultyLevel == 1 ? "Retry" : "Return to last level",
BackgroundColour = colours.Green,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = () => changeDifficulty(Math.Max(difficultyLevel - 1, 1)),
},
new ButtonWithKeyBind(Key.C)
{
Text = $"Continue towards certification at this level ({certificationRemaining} more)",
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Action = () => Action = () =>
{ {
resultsArea.Clear(); isCertifying = false;
totalRoundForNextResultsScreen += rounds_to_complete; changeDifficulty(1);
loadNextRound();
}, },
TooltipText = isPass ? $"Chain {rounds_to_complete_certified} to confirm your perception!" : "You've reached your limits. Go to the previous level to complete certification!", });
Enabled = { Value = isPass }, }
}, else
{
buttonFlow.Add(new ButtonWithKeyBind(Key.Enter)
{
Text = "Begin certification at last level",
BackgroundColour = colours.Yellow,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = () =>
{
isCertifying = true;
changeDifficulty(DifficultyLevel - 1);
},
TooltipText = isPass ? $"Chain {rounds_to_complete_certified} rounds to confirm your perception!" : "You've reached your limits. Go to the previous level to complete certification!",
});
}
}
}
private void showCertifiedScreen()
{
Drawable background;
Drawable certifiedText;
resultsArea.AddRange(new[]
{
background = new Box
{
Colour = overlayColourProvider.Background4,
RelativeSizeAxes = Axes.Both,
},
(certifiedText = new OsuSpriteText
{
Alpha = 0,
Font = OsuFont.TorusAlternate.With(size: 80, weight: FontWeight.Bold),
Text = "Certified!",
Blending = BlendingParameters.Additive,
}).WithEffect(new GlowEffect
{
Colour = overlayColourProvider.Colour1,
PadExtent = true
}).With(e =>
{
e.Anchor = Anchor.Centre;
e.Origin = Anchor.Centre;
}),
new OsuSpriteText
{
Text = $"You should use a frame limiter with update rate of {mapDifficultyToTargetFrameRate(DifficultyLevel + 1)} Hz (or fps) for best results!",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.Torus.With(size: 24, weight: FontWeight.SemiBold),
Y = 80,
} }
}); });
background.FadeInFromZero(1000, Easing.OutQuint);
certifiedText.FadeInFromZero(500, Easing.InQuint);
certifiedText
.ScaleTo(10)
.ScaleTo(1, 600, Easing.InQuad)
.Then()
.ScaleTo(1.05f, 10000, Easing.OutQuint);
} }
private void changeDifficulty(int difficulty) private void changeDifficulty(int difficulty)
@ -344,8 +367,7 @@ Do whatever you need to try and perceive the difference in latency, then choose
pollingMax = 0; pollingMax = 0;
lastPoll = 0; lastPoll = 0;
totalRoundForNextResultsScreen = rounds_to_complete; DifficultyLevel = difficulty;
difficultyLevel = difficulty;
loadNextRound(); loadNextRound();
} }
@ -353,7 +375,7 @@ Do whatever you need to try and perceive the difference in latency, then choose
private void loadNextRound() private void loadNextRound()
{ {
attemptsAtCurrentDifficulty++; attemptsAtCurrentDifficulty++;
statusText.Text = $"Level {difficultyLevel}\nRound {attemptsAtCurrentDifficulty} of {totalRoundForNextResultsScreen}"; statusText.Text = $"Level {DifficultyLevel}\nRound {attemptsAtCurrentDifficulty} of {totalRoundForNextResultsScreen}";
mainArea.Clear(); mainArea.Clear();
@ -361,13 +383,13 @@ Do whatever you need to try and perceive the difference in latency, then choose
mainArea.AddRange(new[] mainArea.AddRange(new[]
{ {
new LatencyArea(Key.Number1, betterSide == 1 ? mapDifficultyToTargetFrameRate(difficultyLevel) : (int?)null) new LatencyArea(Key.Number1, betterSide == 1 ? mapDifficultyToTargetFrameRate(DifficultyLevel) : (int?)null)
{ {
Width = 0.5f, Width = 0.5f,
IsActiveArea = { Value = true }, IsActiveArea = { Value = true },
ReportUserBest = () => recordResult(betterSide == 0), ReportUserBest = () => recordResult(betterSide == 0),
}, },
new LatencyArea(Key.Number2, betterSide == 0 ? mapDifficultyToTargetFrameRate(difficultyLevel) : (int?)null) new LatencyArea(Key.Number2, betterSide == 0 ? mapDifficultyToTargetFrameRate(DifficultyLevel) : (int?)null)
{ {
Width = 0.5f, Width = 0.5f,
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,