diff --git a/osu.Game/Screens/Edit/Timing/TapButton.cs b/osu.Game/Screens/Edit/Timing/TapButton.cs index 59ec966fe0..3eb8e23bad 100644 --- a/osu.Game/Screens/Edit/Timing/TapButton.cs +++ b/osu.Game/Screens/Edit/Timing/TapButton.cs @@ -6,7 +6,10 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osuTK; using osuTK.Graphics; @@ -21,17 +24,23 @@ namespace osu.Game.Screens.Edit.Timing private OverlayColourProvider colourProvider { get; set; } private Circle hoverLayer; + private CircularContainer innerCircle; - private Circle outerCircle; + private Box innerCircleHighlight; + + private int currentLight; private Container scaleContainer; + private Container lights; + + private const int light_count = 6; [BackgroundDependencyLoader] private void load() { Size = new Vector2(SIZE); - const float ring_width = 20; + const float ring_width = 18; const float light_padding = 3; InternalChild = scaleContainer = new Container @@ -41,11 +50,15 @@ namespace osu.Game.Screens.Edit.Timing RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - outerCircle = new Circle + new Circle { RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background3 }, + lights = new Container + { + RelativeSizeAxes = Axes.Both, + }, new CircularContainer { RelativeSizeAxes = Axes.Both, @@ -64,35 +77,65 @@ namespace osu.Game.Screens.Edit.Timing }, } }, + new Circle + { + Size = new Vector2(SIZE - ring_width * 2 + light_padding * 2), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = colourProvider.Background3, + }, innerCircle = new CircularContainer { - Size = new Vector2(SIZE - ring_width + light_padding), + Size = new Vector2(SIZE - ring_width * 2), Anchor = Anchor.Centre, Origin = Anchor.Centre, Masking = true, - BorderThickness = light_padding, - BorderColour = colourProvider.Background3, Children = new Drawable[] { new Box { Colour = colourProvider.Background2, RelativeSizeAxes = Axes.Both, - AlwaysPresent = true, + }, + innerCircleHighlight = new Box + { + Colour = colourProvider.Colour3, + Blending = BlendingParameters.Additive, + RelativeSizeAxes = Axes.Both, + Alpha = 0, + }, + new OsuSpriteText + { + Font = OsuFont.Torus.With(size: 20), + Colour = colourProvider.Background1, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = "Tap!" + }, + hoverLayer = new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background1.Opacity(0.3f), + Blending = BlendingParameters.Additive, + Alpha = 0, }, } }, - hoverLayer = new Circle - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White.Opacity(0.01f), - Blending = BlendingParameters.Additive, - Alpha = 0, - }, } }; + + for (int i = 0; i < light_count; i++) + { + lights.Add(new Light + { + Rotation = i * (360f / light_count) + }); + } } + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + hoverLayer.ReceivePositionalInputAt(screenSpacePos); + protected override bool OnHover(HoverEvent e) { hoverLayer.FadeIn(500, Easing.OutQuint); @@ -107,16 +150,87 @@ namespace osu.Game.Screens.Edit.Timing protected override bool OnMouseDown(MouseDownEvent e) { - scaleContainer.ScaleTo(0.98f, 200, Easing.OutQuint); - innerCircle.ScaleTo(0.95f, 200, Easing.OutQuint); + const double in_duration = 100; + + scaleContainer.ScaleTo(0.99f, in_duration, Easing.OutQuint); + innerCircle.ScaleTo(0.96f, in_duration, Easing.OutQuint); + + innerCircleHighlight + .FadeIn(50, Easing.OutQuint) + .FlashColour(Color4.White, 1000, Easing.OutQuint); + + lights[currentLight % light_count].Hide(); + lights[(currentLight + light_count / 2) % light_count].Hide(); + + currentLight++; + + lights[currentLight % light_count].Show(); + lights[(currentLight + light_count / 2) % light_count].Show(); + return base.OnMouseDown(e); } protected override void OnMouseUp(MouseUpEvent e) { - scaleContainer.ScaleTo(1, 1200, Easing.OutQuint); - innerCircle.ScaleTo(1, 1200, Easing.OutQuint); + const double out_duration = 800; + + scaleContainer.ScaleTo(1, out_duration, Easing.OutQuint); + innerCircle.ScaleTo(1, out_duration, Easing.OutQuint); + innerCircleHighlight.FadeOut(out_duration, Easing.OutQuint); base.OnMouseUp(e); } + + private class Light : CompositeDrawable + { + private CircularProgress fill; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.Both; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + InternalChildren = new Drawable[] + { + new CircularProgress + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(0.99f), + Current = { Value = 1f / light_count - 0.01f }, + Colour = colourProvider.Background2, + }, + fill = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Alpha = 0, + Size = new Vector2(0.99f), + Current = { Value = 1f / light_count - 0.01f }, + Colour = colourProvider.Colour1, + Blending = BlendingParameters.Additive + }, + }; + } + + public override void Show() + { + fill + .FadeIn(50, Easing.OutQuint) + .FlashColour(Color4.White, 1000, Easing.OutQuint); + } + + public override void Hide() + { + fill + .FadeOut(300, Easing.OutQuint); + } + } } }