Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve animation when rotating between available mods #864

Merged
merged 8 commits into from
May 29, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 56 additions & 24 deletions osu.Game/Overlays/Mods/ModButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ModIcon> iconsContainer;
private SampleChannel sampleOn, sampleOff;
Expand All @@ -35,38 +36,67 @@ public class ModButton : ModButtonEmpty, IHasTooltip

public string TooltipText => (SelectedMod?.Description ?? Mods.FirstOrDefault()?.Description) ?? string.Empty;

private int _selectedIndex = -1;
private int selectedIndex
private const EasingTypes mod_switch_easing = EasingTypes.InOutSine;
private const double mod_switch_duration = 120;

// 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;
_selectedIndex = value;
if (value == selectedIndex) return;

int direction = value < selectedIndex ? -1 : 1;
bool beforeSelected = Selected;

Mod modBefore = SelectedMod ?? Mods[0];

if (value >= Mods.Length)
selectedIndex = -1;
else if (value < -1)
selectedIndex = Mods.Length - 1;
else
selectedIndex = value;

Mod modAfter = SelectedMod ?? Mods[0];

if (beforeSelected != Selected)
{
_selectedIndex = -1;
iconsContainer.RotateTo(Selected ? 5f : 0f, 300, EasingTypes.OutElastic);
iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, EasingTypes.OutElastic);
}
else if (value <= -2)

if (modBefore != modAfter)
{
_selectedIndex = Mods.Length - 1;
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 = modAfter.Icon;
using (iconsContainer.BeginDelayedSequence(mod_switch_duration, true))
{
foregroundIcon.RotateTo(-rotate_angle * direction);
foregroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing);

backgroundIcon.RotateTo(rotate_angle * direction);
backgroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing);

iconsContainer.Schedule(() => displayMod(modAfter));
}
}

iconsContainer.RotateTo(Selected ? 5f : 0f, 300, EasingTypes.OutElastic);
iconsContainer.ScaleTo(Selected ? 1.1f : 1f, 300, EasingTypes.OutElastic);
foregroundIcon.Highlighted = Selected;

if (mod != null)
displayMod(SelectedMod ?? Mods[0]);
}
}

public bool Selected => selectedIndex != -1;

public bool Selected => SelectedIndex != -1;

private Color4 selectedColour;
public Color4 SelectedColour
Expand Down Expand Up @@ -117,7 +147,7 @@ public Mod Mod

// 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)
Expand All @@ -142,23 +172,25 @@ protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)

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)
{
if (backgroundIcon != null)
backgroundIcon.Icon = foregroundIcon.Icon;
foregroundIcon.Icon = mod.Icon;
text.Text = mod.Name;
}
Expand All @@ -170,17 +202,17 @@ private void createIcons()
{
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),
},
Expand Down