using System.Collections.Generic; using System.Linq; using Engine.Core; using Engine.Physics2D; using Engine.Systems.Graphics; using Engine.Systems.Tween; namespace Pong.Behaviours; public class BallTrail : Behaviour2D, IPostPhysicsUpdate, IDrawableTriangle { private float width = 10f; private IEasing widthCurve = EaseInCirc.Instance; private ColorRGBA colorBase = new ColorRGBA(255, 255, 255, 255); private ColorRGBA colorEnd = new ColorRGBA(255, 255, 255, 0); private IEasing colorEasing = EaseOutSine.Instance; private int trailTickPeriod = 20; private readonly LinkedList trailPoints = new(); public void PostPhysicsUpdate(float delta) { trailPoints.AddFirst(Transform.Position); if (trailPoints.Count > trailTickPeriod) trailPoints.RemoveLast(); } public void Draw(ITriangleBatch triangleBatch) { for (int i = 0; i < trailPoints.Count - 2; i++) { Line2D line = new(trailPoints.ElementAt(i), trailPoints.ElementAt(i + 1)); Vector2D perpendicularDirection = line.Direction.Perpendicular(); float t = (float)i / trailPoints.Count; float tPlus = (float)(i + 1) / trailPoints.Count; float firstWidth = width * widthCurve.Evaluate(1f - t); float endWidth = width * widthCurve.Evaluate(1f - tPlus); ColorRGBA color = colorBase.Lerp(colorEnd, colorEasing.Evaluate(t)); triangleBatch.Draw( new(line.From + perpendicularDirection * firstWidth, line.From - perpendicularDirection * firstWidth, line.To + perpendicularDirection * endWidth), color ); triangleBatch.Draw( new(line.From - perpendicularDirection * firstWidth, line.To - perpendicularDirection * endWidth, line.To + perpendicularDirection * endWidth), color ); } } }