Create setup for adding other visual display modes

This commit is contained in:
Dean Herbert 2022-06-10 16:22:34 +09:00
parent e5d6dc1ba5
commit 53eb5c176c
7 changed files with 277 additions and 151 deletions

View File

@ -0,0 +1,12 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable enable
using osu.Framework.Graphics.Containers;
namespace osu.Game.Screens.Utility
{
public class CircleGameplay : CompositeDrawable
{
}
}

View File

@ -9,10 +9,9 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Overlays;
using osuTK;
using osu.Game.Screens.Utility.SampleComponents;
using osuTK.Input;
namespace osu.Game.Screens.Utility
@ -28,10 +27,14 @@ namespace osu.Game.Screens.Utility
private readonly Key key;
private Container visualContent = null!;
public readonly int? TargetFrameRate;
public readonly BindableBool IsActiveArea = new BindableBool();
public readonly Bindable<LatencyVisualMode> VisualMode = new Bindable<LatencyVisualMode>();
public LatencyArea(Key key, int? targetFrameRate)
{
this.key = key;
@ -61,20 +64,9 @@ namespace osu.Game.Screens.Utility
Origin = Anchor.TopCentre,
Action = () => ReportUserBest?.Invoke(),
},
new Container
visualContent = new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new LatencyMovableBox(IsActiveArea)
{
RelativeSizeAxes = Axes.Both,
},
new LatencyCursorContainer(IsActiveArea)
{
RelativeSizeAxes = Axes.Both,
},
}
},
};
@ -82,6 +74,57 @@ namespace osu.Game.Screens.Utility
{
background.FadeColour(active.NewValue ? overlayColourProvider.Background4 : overlayColourProvider.Background6, 200, Easing.OutQuint);
}, true);
VisualMode.BindValueChanged(mode =>
{
switch (mode.NewValue)
{
case LatencyVisualMode.Simple:
visualContent.Children = new Drawable[]
{
new LatencyMovableBox(IsActiveArea)
{
RelativeSizeAxes = Axes.Both,
},
new LatencyCursorContainer(IsActiveArea)
{
RelativeSizeAxes = Axes.Both,
},
};
break;
case LatencyVisualMode.CircleGameplay:
visualContent.Children = new Drawable[]
{
new CircleGameplay
{
RelativeSizeAxes = Axes.Both,
},
new LatencyCursorContainer(IsActiveArea)
{
RelativeSizeAxes = Axes.Both,
},
};
break;
case LatencyVisualMode.ScrollingGameplay:
visualContent.Children = new Drawable[]
{
new ScrollingGameplay
{
RelativeSizeAxes = Axes.Both,
},
new LatencyCursorContainer(IsActiveArea)
{
RelativeSizeAxes = Axes.Both,
},
};
break;
default:
throw new ArgumentOutOfRangeException();
}
}, true);
}
protected override bool OnMouseMove(MouseMoveEvent e)
@ -102,140 +145,5 @@ namespace osu.Game.Screens.Utility
return base.UpdateSubTree();
}
public class LatencyMovableBox : CompositeDrawable
{
private Box box = null!;
private InputManager inputManager = null!;
private readonly BindableBool isActive;
[Resolved]
private OverlayColourProvider overlayColourProvider { get; set; } = null!;
public LatencyMovableBox(BindableBool isActive)
{
this.isActive = isActive;
}
protected override void LoadComplete()
{
base.LoadComplete();
inputManager = GetContainingInputManager();
InternalChild = box = new Box
{
Size = new Vector2(40),
RelativePositionAxes = Axes.Both,
Position = new Vector2(0.5f),
Origin = Anchor.Centre,
Colour = overlayColourProvider.Colour1,
};
}
protected override bool OnHover(HoverEvent e) => false;
private double? lastFrameTime;
protected override void Update()
{
base.Update();
if (!isActive.Value)
{
lastFrameTime = null;
box.Colour = overlayColourProvider.Colour1;
return;
}
if (lastFrameTime != null)
{
float movementAmount = (float)(Clock.CurrentTime - lastFrameTime) / 400;
var buttons = inputManager.CurrentState.Keyboard.Keys;
box.Colour = buttons.HasAnyButtonPressed ? overlayColourProvider.Content1 : overlayColourProvider.Colour1;
foreach (var key in buttons)
{
switch (key)
{
case Key.K:
case Key.Up:
box.Y = MathHelper.Clamp(box.Y - movementAmount, 0.1f, 0.9f);
break;
case Key.J:
case Key.Down:
box.Y = MathHelper.Clamp(box.Y + movementAmount, 0.1f, 0.9f);
break;
case Key.Z:
case Key.Left:
box.X = MathHelper.Clamp(box.X - movementAmount, 0.1f, 0.9f);
break;
case Key.X:
case Key.Right:
box.X = MathHelper.Clamp(box.X + movementAmount, 0.1f, 0.9f);
break;
}
}
}
lastFrameTime = Clock.CurrentTime;
}
}
public class LatencyCursorContainer : CompositeDrawable
{
private Circle cursor = null!;
private InputManager inputManager = null!;
private readonly BindableBool isActive;
[Resolved]
private OverlayColourProvider overlayColourProvider { get; set; } = null!;
public LatencyCursorContainer(BindableBool isActive)
{
this.isActive = isActive;
Masking = true;
}
protected override void LoadComplete()
{
base.LoadComplete();
InternalChild = cursor = new Circle
{
Size = new Vector2(40),
Origin = Anchor.Centre,
Colour = overlayColourProvider.Colour2,
};
inputManager = GetContainingInputManager();
}
protected override bool OnHover(HoverEvent e) => false;
protected override void Update()
{
cursor.Colour = inputManager.CurrentState.Mouse.IsPressed(MouseButton.Left) ? overlayColourProvider.Content1 : overlayColourProvider.Colour2;
if (isActive.Value)
{
cursor.Position = ToLocalSpace(inputManager.CurrentState.Mouse.Position);
cursor.Alpha = 1;
}
else
{
cursor.Alpha = 0;
}
base.Update();
}
}
}
}

View File

@ -7,6 +7,7 @@ using System;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Configuration;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@ -62,6 +63,8 @@ namespace osu.Game.Screens.Utility
[Resolved]
private FrameworkConfigManager config { get; set; } = null!;
private readonly Bindable<LatencyVisualMode> visualMode = new Bindable<LatencyVisualMode>();
private const int rounds_to_complete = 5;
private const int rounds_to_complete_certified = 20;
@ -124,8 +127,9 @@ namespace osu.Game.Screens.Utility
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Text = @"Welcome to the latency certifier!
Use the arrow keys, Z/X/J/K to move the square.
Use the arrow keys, Z/X/F/J to control the display.
Use the Tab key to change focus.
Change display modes with Space.
Do whatever you need to try and perceive the difference in latency, then choose your best side.
",
},
@ -182,6 +186,10 @@ Do whatever you need to try and perceive the difference in latency, then choose
{
switch (e.Key)
{
case Key.Space:
visualMode.Value = (LatencyVisualMode)(((int)visualMode.Value + 1) % 3);
return true;
case Key.Tab:
var firstArea = mainArea.FirstOrDefault(a => !a.IsActiveArea.Value);
if (firstArea != null)
@ -301,7 +309,9 @@ Do whatever you need to try and perceive the difference in latency, then choose
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!",
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!",
});
}
}
@ -386,12 +396,14 @@ Do whatever you need to try and perceive the difference in latency, then choose
new LatencyArea(Key.Number1, betterSide == 1 ? mapDifficultyToTargetFrameRate(DifficultyLevel) : (int?)null)
{
Width = 0.5f,
VisualMode = { BindTarget = visualMode },
IsActiveArea = { Value = true },
ReportUserBest = () => recordResult(betterSide == 0),
},
new LatencyArea(Key.Number2, betterSide == 0 ? mapDifficultyToTargetFrameRate(DifficultyLevel) : (int?)null)
{
Width = 0.5f,
VisualMode = { BindTarget = visualMode },
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
ReportUserBest = () => recordResult(betterSide == 1)

View File

@ -0,0 +1,13 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable enable
namespace osu.Game.Screens.Utility
{
public enum LatencyVisualMode
{
Simple,
CircleGameplay,
ScrollingGameplay,
}
}

View File

@ -0,0 +1,67 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable enable
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Overlays;
using osuTK;
using osuTK.Input;
namespace osu.Game.Screens.Utility.SampleComponents
{
public class LatencyCursorContainer : CompositeDrawable
{
private Circle cursor = null!;
private InputManager inputManager = null!;
private readonly BindableBool isActive;
[Resolved]
private OverlayColourProvider overlayColourProvider { get; set; } = null!;
public LatencyCursorContainer(BindableBool isActive)
{
this.isActive = isActive;
Masking = true;
}
protected override void LoadComplete()
{
base.LoadComplete();
InternalChild = cursor = new Circle
{
Size = new Vector2(40),
Origin = Anchor.Centre,
Colour = overlayColourProvider.Colour2,
};
inputManager = GetContainingInputManager();
}
protected override bool OnHover(HoverEvent e) => false;
protected override void Update()
{
cursor.Colour = inputManager.CurrentState.Mouse.IsPressed(MouseButton.Left) ? overlayColourProvider.Content1 : overlayColourProvider.Colour2;
if (isActive.Value)
{
cursor.Position = ToLocalSpace(inputManager.CurrentState.Mouse.Position);
cursor.Alpha = 1;
}
else
{
cursor.Alpha = 0;
}
base.Update();
}
}
}

View File

@ -0,0 +1,102 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable enable
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Overlays;
using osuTK;
using osuTK.Input;
namespace osu.Game.Screens.Utility.SampleComponents
{
public class LatencyMovableBox : CompositeDrawable
{
private Box box = null!;
private InputManager inputManager = null!;
private readonly BindableBool isActive;
[Resolved]
private OverlayColourProvider overlayColourProvider { get; set; } = null!;
public LatencyMovableBox(BindableBool isActive)
{
this.isActive = isActive;
}
protected override void LoadComplete()
{
base.LoadComplete();
inputManager = GetContainingInputManager();
InternalChild = box = new Box
{
Size = new Vector2(40),
RelativePositionAxes = Axes.Both,
Position = new Vector2(0.5f),
Origin = Anchor.Centre,
Colour = overlayColourProvider.Colour1,
};
}
protected override bool OnHover(HoverEvent e) => false;
private double? lastFrameTime;
protected override void Update()
{
base.Update();
if (!isActive.Value)
{
lastFrameTime = null;
box.Colour = overlayColourProvider.Colour1;
return;
}
if (lastFrameTime != null)
{
float movementAmount = (float)(Clock.CurrentTime - lastFrameTime) / 400;
var buttons = inputManager.CurrentState.Keyboard.Keys;
box.Colour = buttons.HasAnyButtonPressed ? overlayColourProvider.Content1 : overlayColourProvider.Colour1;
foreach (var key in buttons)
{
switch (key)
{
case Key.F:
case Key.Up:
box.Y = MathHelper.Clamp(box.Y - movementAmount, 0.1f, 0.9f);
break;
case Key.K:
case Key.Down:
box.Y = MathHelper.Clamp(box.Y + movementAmount, 0.1f, 0.9f);
break;
case Key.Z:
case Key.Left:
box.X = MathHelper.Clamp(box.X - movementAmount, 0.1f, 0.9f);
break;
case Key.X:
case Key.Right:
box.X = MathHelper.Clamp(box.X + movementAmount, 0.1f, 0.9f);
break;
}
}
}
lastFrameTime = Clock.CurrentTime;
}
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable enable
using osu.Framework.Graphics.Containers;
namespace osu.Game.Screens.Utility
{
public class ScrollingGameplay : CompositeDrawable
{
}
}