From 64612ef34b99250921cf96b5c0dfc85ad40f2ea9 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 26 May 2017 16:10:28 +0200 Subject: [PATCH 1/6] add multimod animation --- osu.Game/Overlays/Mods/ModButton.cs | 44 +++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 831b9082bd..68c1fb8592 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -27,6 +27,7 @@ namespace osu.Game.Overlays.Mods public class ModButton : ModButtonEmpty, IHasTooltip { private ModIcon foregroundIcon; + private ModIcon backgroundIcon; private readonly SpriteText text; private readonly Container iconsContainer; private SampleChannel sampleOn, sampleOff; @@ -35,6 +36,9 @@ namespace osu.Game.Overlays.Mods public string TooltipText => (SelectedMod?.Description ?? Mods.FirstOrDefault()?.Description) ?? string.Empty; + private const EasingTypes modSwitchEasing = EasingTypes.InOutQuint; + private const double modSwitchDuration = 100; + private int _selectedIndex = -1; private int selectedIndex { @@ -45,6 +49,9 @@ namespace osu.Game.Overlays.Mods set { if (value == _selectedIndex) return; + + bool beforeSelected = Selected; + _selectedIndex = value; if (value >= Mods.Length) @@ -55,13 +62,30 @@ namespace osu.Game.Overlays.Mods { _selectedIndex = Mods.Length - 1; } - - iconsContainer.RotateTo(Selected ? 5f : 0f, 300, EasingTypes.OutElastic); - iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, EasingTypes.OutElastic); + if (beforeSelected ^ Selected) + { + iconsContainer.RotateTo(Selected ? 5f : 0f, 300, EasingTypes.OutElastic); + iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, EasingTypes.OutElastic); + } + else + { + foregroundIcon.RotateTo(15f, modSwitchDuration, modSwitchEasing); + backgroundIcon.RotateTo(-15f, modSwitchDuration, modSwitchEasing); + using (foregroundIcon.BeginDelayedSequence(modSwitchDuration)) + { + foregroundIcon.RotateTo(-15f); + foregroundIcon.RotateTo(0f, modSwitchDuration, modSwitchEasing); + } + using (backgroundIcon.BeginDelayedSequence(modSwitchDuration)) + { + backgroundIcon.RotateTo(15f); + backgroundIcon.RotateTo(0f, modSwitchDuration, modSwitchEasing); + } + } foregroundIcon.Highlighted = Selected; if (mod != null) - displayMod(SelectedMod ?? Mods[0]); + Scheduler.AddDelayed(() => displayMod(SelectedMod ?? Mods[0]), beforeSelected ^ Selected ? 0 : modSwitchDuration); } } @@ -159,6 +183,8 @@ namespace osu.Game.Overlays.Mods private void displayMod(Mod mod) { + if(backgroundIcon != null) + backgroundIcon.Icon = foregroundIcon.Icon; foregroundIcon.Icon = mod.Icon; text.Text = mod.Name; } @@ -170,17 +196,17 @@ namespace osu.Game.Overlays.Mods { iconsContainer.Add(new[] { - new ModIcon(Mods[0]) + backgroundIcon = new ModIcon(Mods[1]) { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, + Origin = Anchor.BottomRight, + Anchor = Anchor.BottomRight, AutoSizeAxes = Axes.Both, Position = new Vector2(1.5f), }, foregroundIcon = new ModIcon(Mods[0]) { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, + Origin = Anchor.BottomRight, + Anchor = Anchor.BottomRight, AutoSizeAxes = Axes.Both, Position = new Vector2(-1.5f), }, From db1dde72de27b276a023932e7ae999986b7882dc Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 26 May 2017 16:29:15 +0200 Subject: [PATCH 2/6] change constant names --- osu.Game/Overlays/Mods/ModButton.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 68c1fb8592..e1545ab1b8 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -36,8 +36,8 @@ namespace osu.Game.Overlays.Mods public string TooltipText => (SelectedMod?.Description ?? Mods.FirstOrDefault()?.Description) ?? string.Empty; - private const EasingTypes modSwitchEasing = EasingTypes.InOutQuint; - private const double modSwitchDuration = 100; + private const EasingTypes mod_switch_easing = EasingTypes.InOutQuint; + private const double mod_switch_duration = 100; private int _selectedIndex = -1; private int selectedIndex @@ -69,23 +69,23 @@ namespace osu.Game.Overlays.Mods } else { - foregroundIcon.RotateTo(15f, modSwitchDuration, modSwitchEasing); - backgroundIcon.RotateTo(-15f, modSwitchDuration, modSwitchEasing); - using (foregroundIcon.BeginDelayedSequence(modSwitchDuration)) + foregroundIcon.RotateTo(15f, mod_switch_duration, mod_switch_easing); + backgroundIcon.RotateTo(-15f, mod_switch_duration, mod_switch_easing); + using (foregroundIcon.BeginDelayedSequence(mod_switch_duration)) { foregroundIcon.RotateTo(-15f); - foregroundIcon.RotateTo(0f, modSwitchDuration, modSwitchEasing); + foregroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); } - using (backgroundIcon.BeginDelayedSequence(modSwitchDuration)) + using (backgroundIcon.BeginDelayedSequence(mod_switch_duration)) { backgroundIcon.RotateTo(15f); - backgroundIcon.RotateTo(0f, modSwitchDuration, modSwitchEasing); + backgroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); } } foregroundIcon.Highlighted = Selected; if (mod != null) - Scheduler.AddDelayed(() => displayMod(SelectedMod ?? Mods[0]), beforeSelected ^ Selected ? 0 : modSwitchDuration); + Scheduler.AddDelayed(() => displayMod(SelectedMod ?? Mods[0]), beforeSelected ^ Selected ? 0 : mod_switch_duration); } } From e86ccf61b3f70dfd8a22d4838d6789d2d8f94b4c Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 27 May 2017 09:52:02 +0200 Subject: [PATCH 3/6] use recursion --- osu.Game/Overlays/Mods/ModButton.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index e1545ab1b8..70197ba444 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -71,13 +71,11 @@ namespace osu.Game.Overlays.Mods { foregroundIcon.RotateTo(15f, mod_switch_duration, mod_switch_easing); backgroundIcon.RotateTo(-15f, mod_switch_duration, mod_switch_easing); - using (foregroundIcon.BeginDelayedSequence(mod_switch_duration)) + using (iconsContainer.BeginDelayedSequence(mod_switch_duration, true)) { foregroundIcon.RotateTo(-15f); foregroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); - } - using (backgroundIcon.BeginDelayedSequence(mod_switch_duration)) - { + backgroundIcon.RotateTo(15f); backgroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); } From 31cc6917bc5b11774a8d557a86902692e9a95e85 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 29 May 2017 17:20:55 +0900 Subject: [PATCH 4/6] Tidy up code, improve transition, add directionality --- osu.Game/Overlays/Mods/ModButton.cs | 57 ++++++++++++++++------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 70197ba444..f13b60a3ca 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -36,59 +36,64 @@ namespace osu.Game.Overlays.Mods public string TooltipText => (SelectedMod?.Description ?? Mods.FirstOrDefault()?.Description) ?? string.Empty; - private const EasingTypes mod_switch_easing = EasingTypes.InOutQuint; - private const double mod_switch_duration = 100; + private const EasingTypes mod_switch_easing = EasingTypes.InOutSine; + private const double mod_switch_duration = 140; - private int _selectedIndex = -1; - private int selectedIndex + // A selected index of -1 means not selected. + private int selectedIndex = -1; + + protected int SelectedIndex { get { - return _selectedIndex; + return selectedIndex; } set { - if (value == _selectedIndex) return; + if (value == selectedIndex) return; bool beforeSelected = Selected; - _selectedIndex = value; + int direction = value < selectedIndex ? -1 : 1; + + selectedIndex = value; if (value >= Mods.Length) - { - _selectedIndex = -1; - } + selectedIndex = -1; else if (value <= -2) - { - _selectedIndex = Mods.Length - 1; - } + selectedIndex = Mods.Length - 1; + if (beforeSelected ^ Selected) { iconsContainer.RotateTo(Selected ? 5f : 0f, 300, EasingTypes.OutElastic); iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, EasingTypes.OutElastic); + displayMod(SelectedMod ?? Mods[0]); } else { - foregroundIcon.RotateTo(15f, mod_switch_duration, mod_switch_easing); - backgroundIcon.RotateTo(-15f, mod_switch_duration, mod_switch_easing); + const float rotate_angle = 16; + + foregroundIcon.RotateTo(rotate_angle * direction, mod_switch_duration, mod_switch_easing); + backgroundIcon.RotateTo(-rotate_angle * direction, mod_switch_duration, mod_switch_easing); + + backgroundIcon.Icon = SelectedMod.Icon; using (iconsContainer.BeginDelayedSequence(mod_switch_duration, true)) { - foregroundIcon.RotateTo(-15f); + foregroundIcon.RotateTo(-rotate_angle * direction); foregroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); - backgroundIcon.RotateTo(15f); + backgroundIcon.RotateTo(rotate_angle * direction); backgroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); + + iconsContainer.Schedule(() => displayMod(SelectedMod ?? Mods[0])); } } - foregroundIcon.Highlighted = Selected; - if (mod != null) - Scheduler.AddDelayed(() => displayMod(SelectedMod ?? Mods[0]), beforeSelected ^ Selected ? 0 : mod_switch_duration); + foregroundIcon.Highlighted = Selected; } } - public bool Selected => selectedIndex != -1; - + public bool Selected => SelectedIndex != -1; private Color4 selectedColour; public Color4 SelectedColour @@ -139,7 +144,7 @@ namespace osu.Game.Overlays.Mods // the mods from Mod, only multiple if Mod is a MultiMod - public override Mod SelectedMod => Mods.ElementAtOrDefault(selectedIndex); + public override Mod SelectedMod => Mods.ElementAtOrDefault(SelectedIndex); [BackgroundDependencyLoader] private void load(AudioManager audio) @@ -164,19 +169,19 @@ namespace osu.Game.Overlays.Mods public void SelectNext() { - (++selectedIndex == -1 ? sampleOff : sampleOn).Play(); + (++SelectedIndex == -1 ? sampleOff : sampleOn).Play(); Action?.Invoke(SelectedMod); } public void SelectPrevious() { - (--selectedIndex == -1 ? sampleOff : sampleOn).Play(); + (--SelectedIndex == -1 ? sampleOff : sampleOn).Play(); Action?.Invoke(SelectedMod); } public void Deselect() { - selectedIndex = -1; + SelectedIndex = -1; } private void displayMod(Mod mod) From 7960b5cf26ea4209aa57861c83c905e2600a7de0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 29 May 2017 18:03:40 +0900 Subject: [PATCH 5/6] More refactoring Also allows rotation when reaching the end of the available mods. --- osu.Game/Overlays/Mods/ModButton.cs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index f13b60a3ca..9ff19caff3 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Mods public string TooltipText => (SelectedMod?.Description ?? Mods.FirstOrDefault()?.Description) ?? string.Empty; private const EasingTypes mod_switch_easing = EasingTypes.InOutSine; - private const double mod_switch_duration = 140; + private const double mod_switch_duration = 120; // A selected index of -1 means not selected. private int selectedIndex = -1; @@ -52,31 +52,34 @@ namespace osu.Game.Overlays.Mods { if (value == selectedIndex) return; + int direction = value < selectedIndex ? -1 : 1; bool beforeSelected = Selected; - int direction = value < selectedIndex ? -1 : 1; - - selectedIndex = value; + Mod modBefore = SelectedMod ?? Mods[0]; if (value >= Mods.Length) selectedIndex = -1; - else if (value <= -2) + else if (value < -1) selectedIndex = Mods.Length - 1; + else + selectedIndex = value; - if (beforeSelected ^ Selected) + Mod modAfter = SelectedMod ?? Mods[0]; + + if (beforeSelected != Selected) { iconsContainer.RotateTo(Selected ? 5f : 0f, 300, EasingTypes.OutElastic); iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, EasingTypes.OutElastic); - displayMod(SelectedMod ?? Mods[0]); } - else + + if (modBefore != modAfter) { const float rotate_angle = 16; foregroundIcon.RotateTo(rotate_angle * direction, mod_switch_duration, mod_switch_easing); backgroundIcon.RotateTo(-rotate_angle * direction, mod_switch_duration, mod_switch_easing); - backgroundIcon.Icon = SelectedMod.Icon; + backgroundIcon.Icon = modAfter.Icon; using (iconsContainer.BeginDelayedSequence(mod_switch_duration, true)) { foregroundIcon.RotateTo(-rotate_angle * direction); @@ -85,7 +88,7 @@ namespace osu.Game.Overlays.Mods backgroundIcon.RotateTo(rotate_angle * direction); backgroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); - iconsContainer.Schedule(() => displayMod(SelectedMod ?? Mods[0])); + iconsContainer.Schedule(() => displayMod(modAfter)); } } From e4b876ff5b7e274a12bb80ab2b3f14384cf09f78 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 29 May 2017 18:10:02 +0900 Subject: [PATCH 6/6] Update ModButton.cs --- osu.Game/Overlays/Mods/ModButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 9ff19caff3..f7df67b66d 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -189,7 +189,7 @@ namespace osu.Game.Overlays.Mods private void displayMod(Mod mod) { - if(backgroundIcon != null) + if (backgroundIcon != null) backgroundIcon.Icon = foregroundIcon.Icon; foregroundIcon.Icon = mod.Icon; text.Text = mod.Name;