diff --git a/osu.Desktop.Tests/Visual/TestCaseCatcher.cs b/osu.Desktop.Tests/Visual/TestCaseCatcher.cs
new file mode 100644
index 0000000000..eb714c9994
--- /dev/null
+++ b/osu.Desktop.Tests/Visual/TestCaseCatcher.cs
@@ -0,0 +1,26 @@
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.Catch.UI;
+using OpenTK;
+
+namespace osu.Desktop.Tests.Visual
+{
+ internal class TestCaseCatcher : OsuTestCase
+ {
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ Children = new Drawable[]
+ {
+ new CatcherArea
+ {
+ RelativePositionAxes = Axes.Both,
+ RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Size = new Vector2(1, 0.2f),
+ }
+ };
+ }
+ }
+}
diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj
index aa862498d1..ba8ae06863 100644
--- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj
+++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj
@@ -71,6 +71,7 @@
+
diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
index ba766fa61b..03aabc5632 100644
--- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
@@ -20,14 +20,12 @@ namespace osu.Game.Rulesets.Catch.UI
Children = new Drawable[]
{
- new Catcher
+ new CatcherArea
{
- RelativePositionAxes = Axes.Both,
RelativeSizeAxes = Axes.Both,
- Scale = new Vector2(0.2f),
- FillMode = FillMode.Fit,
- Origin = Anchor.TopCentre,
- Position = new Vector2(0.5f, 1),
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.TopLeft,
+ Height = 0.3f
}
};
}
diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs
deleted file mode 100644
index 42e4f03da1..0000000000
--- a/osu.Game.Rulesets.Catch/UI/Catcher.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System;
-using osu.Framework.Allocation;
-using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.Textures;
-using osu.Framework.Input;
-using OpenTK;
-using OpenTK.Input;
-
-namespace osu.Game.Rulesets.Catch.UI
-{
- public class Catcher : Sprite
- {
- public override bool HandleInput => true;
-
- [BackgroundDependencyLoader]
- private void load(TextureStore textures)
- {
- Texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
- }
-
- private bool leftPressed;
- private bool rightPressed;
-
- private int currentDirection;
-
- protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
- {
- if (args.Repeat) return true;
-
- switch (args.Key)
- {
- case Key.Left:
- currentDirection = -1;
- leftPressed = true;
- return true;
- case Key.Right:
- currentDirection = 1;
- rightPressed = true;
- return true;
- }
-
- return base.OnKeyDown(state, args);
- }
-
- protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
- {
- switch (args.Key)
- {
- case Key.Left:
- currentDirection = rightPressed ? 1 : 0;
- leftPressed = false;
-
- return true;
- case Key.Right:
- currentDirection = leftPressed ? -1 : 0;
- rightPressed = false;
- return true;
- }
-
- return base.OnKeyUp(state, args);
- }
-
- protected override void Update()
- {
- base.Update();
-
- if (currentDirection == 0) return;
-
- Scale = new Vector2(Scale.X * (Math.Sign(currentDirection) != Math.Sign(Scale.X) ? -1 : 1), Scale.Y);
- X = (float)MathHelper.Clamp(X + currentDirection * Clock.ElapsedFrameTime / 1000, 0, 1);
- }
- }
-}
diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
new file mode 100644
index 0000000000..cb979ffc55
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
@@ -0,0 +1,143 @@
+using System;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.Textures;
+using osu.Framework.Input;
+using OpenTK;
+using OpenTK.Input;
+
+namespace osu.Game.Rulesets.Catch.UI
+{
+ public class CatcherArea : Container
+ {
+ public override bool HandleInput => true;
+
+ private Sprite catcher;
+
+ private Drawable createAdditiveFrame() => new Sprite
+ {
+ RelativePositionAxes = Axes.Both,
+ Anchor = Anchor.TopLeft,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.Both,
+ FillMode = FillMode.Fit,
+
+ Texture = catcher.Texture,
+ BlendingMode = BlendingMode.Additive,
+ Position = catcher.Position,
+ Scale = catcher.Scale,
+ };
+
+ [BackgroundDependencyLoader]
+ private void load(TextureStore textures)
+ {
+ Children = new Drawable[]
+ {
+ catcher = new Sprite
+ {
+ RelativePositionAxes = Axes.Both,
+ Anchor = Anchor.TopLeft,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.Both,
+ FillMode = FillMode.Fit,
+
+ X = 0.5f,
+ Texture = textures.Get(@"Play/Catch/fruit-catcher-idle"),
+ },
+ };
+ }
+
+ private bool leftPressed;
+ private bool rightPressed;
+
+ private int currentDirection;
+
+ private bool dashing;
+
+ protected bool Dashing
+ {
+ get
+ {
+ return dashing;
+ }
+ set
+ {
+ if (value == dashing) return;
+
+ dashing = value;
+
+ if (dashing)
+ Schedule(addAdditiveSprite);
+ }
+ }
+
+ private void addAdditiveSprite()
+ {
+ if (!dashing) return;
+
+ var additive = createAdditiveFrame();
+
+ Add(additive);
+
+ additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint).Expire();
+
+ Scheduler.AddDelayed(addAdditiveSprite, 50);
+ }
+
+ protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
+ {
+ if (args.Repeat) return true;
+
+ switch (args.Key)
+ {
+ case Key.Left:
+ currentDirection = -1;
+ leftPressed = true;
+ return true;
+ case Key.Right:
+ currentDirection = 1;
+ rightPressed = true;
+ return true;
+ case Key.ShiftLeft:
+ Dashing = true;
+ return true;
+ }
+
+ return base.OnKeyDown(state, args);
+ }
+
+ protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
+ {
+ switch (args.Key)
+ {
+ case Key.Left:
+ currentDirection = rightPressed ? 1 : 0;
+ leftPressed = false;
+ return true;
+ case Key.Right:
+ currentDirection = leftPressed ? -1 : 0;
+ rightPressed = false;
+ return true;
+ case Key.ShiftLeft:
+ Dashing = false;
+ return true;
+ }
+
+ return base.OnKeyUp(state, args);
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ if (currentDirection == 0) return;
+
+ float speed = Dashing ? 1.5f : 1;
+
+ catcher.Scale = new Vector2(Math.Sign(currentDirection), 1);
+ catcher.X = (float)MathHelper.Clamp(catcher.X + currentDirection * Clock.ElapsedFrameTime / 1800 * speed, 0, 1);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
index f84f9302bb..003fe2763e 100644
--- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
+++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
@@ -57,7 +57,7 @@
-
+