diff options
author | chai <215380520@qq.com> | 2024-06-03 10:15:45 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2024-06-03 10:15:45 +0800 |
commit | acea7b2e728787a0d83bbf83c8c1f042d2c32e7e (patch) | |
tree | 0bfec05c1ca2d71be2c337bcd110a0421f19318b /Plugins/MonoGame.Extended/source/MonoGame.Extended.Tweening/Tween.cs | |
parent | 88febcb02bf127d961c6471d9e846c0e1315f5c3 (diff) |
+ plugins project
Diffstat (limited to 'Plugins/MonoGame.Extended/source/MonoGame.Extended.Tweening/Tween.cs')
-rw-r--r-- | Plugins/MonoGame.Extended/source/MonoGame.Extended.Tweening/Tween.cs | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tweening/Tween.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tweening/Tween.cs new file mode 100644 index 0000000..ad29251 --- /dev/null +++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tweening/Tween.cs @@ -0,0 +1,184 @@ +using System; +using Microsoft.Xna.Framework; + +namespace MonoGame.Extended.Tweening +{ + public abstract class Tween<T> : Tween + where T : struct + { + internal Tween(object target, float duration, float delay, TweenMember<T> member, T endValue) + : base(target, duration, delay) + { + Member = member; + _endValue = endValue; + } + + public TweenMember<T> Member { get; } + public override string MemberName => Member.Name; + + protected T _startValue; + protected T _endValue; + + protected override void Initialize() + { + _startValue = Member.Value; + } + + protected override void Swap() + { + _endValue = _startValue; + Initialize(); + } + } + + public abstract class Tween + { + internal Tween(object target, float duration, float delay) + { + Target = target; + Duration = duration; + Delay = delay; + IsAlive = true; + + _remainingDelay = delay; + } + + public object Target { get; } + public abstract string MemberName { get; } + public float Duration { get; } + public float Delay { get; } + public bool IsPaused { get; set; } + public bool IsRepeating => _remainingRepeats != 0; + public bool IsRepeatingForever => _remainingRepeats < 0; + public bool IsAutoReverse { get; private set; } + public bool IsAlive { get; private set; } + public bool IsComplete { get; private set; } + public float TimeRemaining => Duration - _elapsedDuration; + public float Completion => MathHelper.Clamp(_completion, 0, 1); + + private Func<float, float> _easingFunction; + private bool _isInitialized; + private float _completion; + private float _elapsedDuration; + private float _remainingDelay; + private float _repeatDelay; + private int _remainingRepeats; + private Action<Tween> _onBegin; + private Action<Tween> _onEnd; + + public Tween Easing(Func<float, float> easingFunction) { _easingFunction = easingFunction; return this; } + public Tween OnBegin(Action<Tween> action) { _onBegin = action; return this; } + public Tween OnEnd(Action<Tween> action) { _onEnd = action; return this; } + public Tween Pause() { IsPaused = true; return this; } + public Tween Resume() { IsPaused = false; return this; } + + public Tween Repeat(int count, float repeatDelay = 0f) + { + _remainingRepeats = count; + _repeatDelay = repeatDelay; + return this; + } + + public Tween RepeatForever(float repeatDelay = 0f) + { + _remainingRepeats = -1; + _repeatDelay = repeatDelay; + return this; + } + + public Tween AutoReverse() + { + if (_remainingRepeats == 0) + _remainingRepeats = 1; + + IsAutoReverse = true; + return this; + } + + protected abstract void Initialize(); + protected abstract void Interpolate(float n); + protected abstract void Swap(); + + public void Cancel() + { + _remainingRepeats = 0; + IsAlive = false; + } + + public void CancelAndComplete() + { + if (IsAlive) + { + _completion = 1; + + Interpolate(1); + IsComplete = true; + _onEnd?.Invoke(this); + } + + Cancel(); + } + + public void Update(float elapsedSeconds) + { + if(IsPaused || !IsAlive) + return; + + if (_remainingDelay > 0) + { + _remainingDelay -= elapsedSeconds; + + if (_remainingDelay > 0) + return; + } + + if (!_isInitialized) + { + _isInitialized = true; + Initialize(); + _onBegin?.Invoke(this); + } + + if (IsComplete) + { + IsComplete = false; + _elapsedDuration = 0; + _onBegin?.Invoke(this); + + if (IsAutoReverse) + Swap(); + } + + _elapsedDuration += elapsedSeconds; + + var n = _completion = _elapsedDuration / Duration; + + if (_easingFunction != null) + n = _easingFunction(n); + + if (_elapsedDuration >= Duration) + { + if (_remainingRepeats != 0) + { + if(_remainingRepeats > 0) + _remainingRepeats--; + + _remainingDelay = _repeatDelay; + } + else if (_remainingRepeats == 0) + { + IsAlive = false; + } + + n = _completion = 1; + IsComplete = true; + } + + Interpolate(n); + + if (IsComplete) + _onEnd?.Invoke(this); + } + + } +} |