From acea7b2e728787a0d83bbf83c8c1f042d2c32e7e Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Mon, 3 Jun 2024 10:15:45 +0800 Subject: + plugins project --- .../source/MonoGame.Extended.Tweening/Tween.cs | 184 +++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 Plugins/MonoGame.Extended/source/MonoGame.Extended.Tweening/Tween.cs (limited to 'Plugins/MonoGame.Extended/source/MonoGame.Extended.Tweening/Tween.cs') 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 : Tween + where T : struct + { + internal Tween(object target, float duration, float delay, TweenMember member, T endValue) + : base(target, duration, delay) + { + Member = member; + _endValue = endValue; + } + + public TweenMember 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 _easingFunction; + private bool _isInitialized; + private float _completion; + private float _elapsedDuration; + private float _remainingDelay; + private float _repeatDelay; + private int _remainingRepeats; + private Action _onBegin; + private Action _onEnd; + + public Tween Easing(Func easingFunction) { _easingFunction = easingFunction; return this; } + public Tween OnBegin(Action action) { _onBegin = action; return this; } + public Tween OnEnd(Action 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); + } + + } +} -- cgit v1.1-26-g67d0