// 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); } } }