osu/osu.Game/Graphics/Containers/ShakeContainer.cs
2019-11-11 20:13:13 +08:00

56 lines
1.9 KiB
C#

// 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.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
namespace osu.Game.Graphics.Containers
{
/// <summary>
/// A container that adds the ability to shake its contents.
/// </summary>
public class ShakeContainer : Container
{
/// <summary>
/// The length of a single shake.
/// </summary>
public float ShakeDuration = 80;
/// <summary>
/// Total number of shakes. May be shortened if possible.
/// </summary>
public float TotalShakes = 4;
/// <summary>
/// Pixels of displacement per shake.
/// </summary>
public float ShakeMagnitude = 8;
/// <summary>
/// Shake the contents of this container.
/// </summary>
/// <param name="maximumLength">The maximum length the shake should last.</param>
public void Shake(double? maximumLength = null)
{
const float shake_amount = 8;
// if we don't have enough time, don't bother shaking.
if (maximumLength < ShakeDuration * 2)
return;
var sequence = this.MoveToX(shake_amount, ShakeDuration / 2, Easing.OutSine).Then()
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
// if we don't have enough time for the second shake, skip it.
if (!maximumLength.HasValue || maximumLength >= ShakeDuration * 4)
{
sequence = sequence
.MoveToX(shake_amount, ShakeDuration, Easing.InOutSine).Then()
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
}
sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine);
}
}
}