Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Microsoft.Xna.Framework;
- namespace Lemma.Components
- {
- public class Animation : Component, IUpdateableComponent
- {
- public abstract class Base
- {
- public bool Done { get; protected set; }
- public abstract void Reset();
- public abstract void Update(float dt);
- }
- public abstract class Interval : Base
- {
- public float Duration { get; private set; }
- private float time;
- public Interval(float duration)
- {
- this.Duration = duration;
- }
- public override void Reset()
- {
- this.time = 0.0f;
- this.Done = false;
- }
- public sealed override void Update(float dt)
- {
- this.time += dt;
- this.UpdateInterval(Math.Min(this.time / this.Duration, 1.0f));
- this.Done = this.time > this.Duration;
- }
- public abstract void UpdateInterval(float x);
- }
- public abstract class Move<T> : Interval
- {
- protected Property<T> property;
- protected T start;
- protected T parameter;
- public Move(Property<T> p, T t, float duration)
- : base(duration)
- {
- this.property = p;
- this.start = p;
- this.parameter = t;
- }
- }
- public class Vector2MoveTo : Move<Vector2>
- {
- public Vector2MoveTo(Property<Vector2> p, Vector2 t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = this.start + (this.parameter - this.start) * x;
- }
- }
- public class Vector2MoveBy : Move<Vector2>
- {
- public Vector2MoveBy(Property<Vector2> p, Vector2 t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = this.start + this.parameter * x;
- }
- }
- public class Vector3MoveTo : Move<Vector3>
- {
- public Vector3MoveTo(Property<Vector3> p, Vector3 t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = this.start + (this.parameter - this.start) * x;
- }
- }
- public class Vector3MoveBy : Move<Vector3>
- {
- public Vector3MoveBy(Property<Vector3> p, Vector3 t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = this.start + this.parameter * x;
- }
- }
- public class Vector4MoveTo : Move<Vector4>
- {
- public Vector4MoveTo(Property<Vector4> p, Vector4 t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = this.start + (this.parameter - this.start) * x;
- }
- }
- public class ColorMoveTo : Move<Color>
- {
- public ColorMoveTo(Property<Color> p, Color t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = new Color(this.start.ToVector4() + (this.parameter.ToVector4() - this.start.ToVector4()) * x);
- }
- }
- public class Vector4MoveBy : Move<Vector4>
- {
- public Vector4MoveBy(Property<Vector4> p, Vector4 t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = this.start + this.parameter * x;
- }
- }
- public class FloatMoveTo : Move<float>
- {
- public FloatMoveTo(Property<float> p, float t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = this.start + (this.parameter - this.start) * x;
- }
- }
- public class FloatMoveBy : Move<float>
- {
- public FloatMoveBy(Property<float> p, float t, float duration)
- : base(p, t, duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- this.property.Value = this.start + this.parameter * x;
- }
- }
- public class Delay : Interval
- {
- public Delay(float duration)
- : base(duration)
- {
- }
- public override void UpdateInterval(float x)
- {
- // Do nothing!
- }
- }
- public class Execute : Interval
- {
- private Action action;
- private bool executed;
- public Execute(Action action)
- : base(0)
- {
- this.action = action;
- }
- public override void Reset()
- {
- base.Reset();
- this.executed = false;
- }
- public override void UpdateInterval(float x)
- {
- if (!this.executed)
- this.action();
- this.executed = true;
- }
- }
- public class Parallel : Interval
- {
- private bool[] finished;
- private Interval[] intervals;
- public Parallel(params Interval[] intervals)
- : base(intervals.Max(x => x.Duration))
- {
- this.intervals = intervals;
- this.finished = new bool[this.intervals.Length];
- }
- public override void Reset()
- {
- base.Reset();
- foreach (Interval i in this.intervals)
- i.Reset();
- for (int i = 0; i < this.finished.Length; i++)
- this.finished[i] = false;
- }
- public override void UpdateInterval(float x)
- {
- float time = x * this.Duration;
- for (int i = 0; i < this.intervals.Length; i++)
- {
- Interval interval = this.intervals[i];
- float intervalTime = time / interval.Duration;
- if (intervalTime >= 1.0f)
- {
- if (!this.finished[i])
- {
- interval.UpdateInterval(1.0f);
- this.finished[i] = true;
- }
- }
- else
- interval.UpdateInterval(intervalTime);
- }
- }
- }
- public class Sequence : Interval
- {
- private float[] criticalPoints;
- private Interval[] intervals;
- private int currentIndex;
- public Sequence(params Interval[] intervals)
- : base(intervals.Sum(x => x.Duration))
- {
- this.intervals = intervals;
- this.criticalPoints = new float[this.intervals.Length];
- float total = 0.0f;
- int i = 0;
- foreach (Interval interval in this.intervals)
- {
- this.criticalPoints[i] = total;
- total += interval.Duration / this.Duration;
- i++;
- }
- }
- public override void Reset()
- {
- base.Reset();
- this.currentIndex = 0;
- foreach (Interval i in this.intervals)
- i.Reset();
- }
- public override void UpdateInterval(float x)
- {
- // Advance the index if necessary
- int maxIndex = this.intervals.Length - 1;
- if (this.currentIndex < maxIndex)
- {
- while (x >= this.criticalPoints[this.currentIndex + 1])
- {
- this.intervals[this.currentIndex].UpdateInterval(1.0f);
- this.currentIndex++;
- if (this.currentIndex == maxIndex)
- break;
- }
- }
- // Retreat the index if necessary
- if (this.currentIndex > 0)
- {
- while (x < this.criticalPoints[this.currentIndex])
- {
- this.intervals[this.currentIndex].UpdateInterval(0.0f);
- this.currentIndex--;
- }
- }
- // Update the current interval
- float lastCriticalPoint = this.criticalPoints[this.currentIndex];
- float nextCriticalPoint = this.currentIndex >= maxIndex ? 1.0f : this.criticalPoints[this.currentIndex + 1];
- this.intervals[this.currentIndex].UpdateInterval((x - lastCriticalPoint) / (nextCriticalPoint - lastCriticalPoint));
- }
- }
- public class Repeat : Interval
- {
- private Interval interval;
- private int count;
- private int index;
- public Repeat(Interval interval, int count)
- : base(interval.Duration * count)
- {
- this.interval = interval;
- this.count = count;
- }
- public override void Reset()
- {
- base.Reset();
- this.interval.Reset();
- this.index = 0;
- }
- public override void UpdateInterval(float x)
- {
- float d = x / (1.0f / this.count);
- int newIndex = (int)Math.Floor(d);
- if (newIndex != this.index)
- this.interval.Reset();
- this.index = newIndex;
- this.interval.UpdateInterval(d - newIndex);
- }
- }
- public class Reverse : Interval
- {
- private Interval interval;
- public Reverse(Interval interval)
- : base(interval.Duration)
- {
- this.interval = interval;
- }
- public override void Reset()
- {
- base.Reset();
- this.interval.Reset();
- }
- public override void UpdateInterval(float x)
- {
- this.interval.UpdateInterval(1.0f - x);
- }
- }
- public class Speed : Interval
- {
- private Interval interval;
- private float speed;
- public Speed(Interval interval, float speed)
- : base(interval.Duration / speed)
- {
- this.interval = interval;
- this.speed = speed;
- }
- public override void Reset()
- {
- base.Reset();
- this.interval.Reset();
- }
- public override void UpdateInterval(float x)
- {
- this.interval.UpdateInterval(x);
- }
- }
- public class RepeatForever : Base
- {
- private Interval interval;
- private float time;
- public RepeatForever(Interval interval)
- {
- this.interval = interval;
- }
- public override void Reset()
- {
- this.interval.Reset();
- this.time = 0.0f;
- }
- public sealed override void Update(float dt)
- {
- if (this.time > this.interval.Duration)
- {
- this.interval.Reset();
- this.time = 0.0f;
- }
- this.time += dt;
- this.interval.UpdateInterval(this.time / this.interval.Duration);
- }
- }
- private Base action;
- public float RunTime { get; private set; }
- public Animation(Base action)
- {
- this.action = action;
- }
- public Animation(params Interval[] intervals)
- {
- if (intervals.Length == 1)
- this.action = intervals[0];
- else
- this.action = new Sequence(intervals);
- }
- void IUpdateableComponent.Update(float dt)
- {
- if (this.action.Done)
- this.Delete();
- else
- {
- this.RunTime += dt;
- this.action.Update(dt);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement