using System.Collections.Generic; using Microsoft.Xna.Framework.Graphics; using Engine.Core; namespace Engine.Integration.MonoGame; public class SpriteBatcher : Behaviour, IFirstFrameUpdate, IDraw { private static Comparer SortByPriority() => Comparer.Create((x, y) => y.CompareTo(x)); private static System.Func GetPriority() => (b) => b.Priority; private ISpriteBatch spriteBatch = null!; private MonoGameCamera2D camera2D = null!; private readonly RasterizerState rasterizerState = new() { CullMode = CullMode.CullClockwiseFace }; private readonly ActiveBehaviourCollectorOrdered drawableSprites = new(GetPriority(), SortByPriority()); public void FirstActiveFrame() { MonoGameWindowContainer windowContainer = Universe.FindRequiredBehaviour(); camera2D = Universe.FindRequiredBehaviour(); spriteBatch = new SpriteBatchWrapper(windowContainer.Window.GraphicsDevice); drawableSprites.Unassign(); drawableSprites.Assign(Universe); } public void Draw() { Matrix4x4 transformMatrix = Matrix4x4.Identity .ApplyTranslation(new Vector2D(camera2D.Viewport.X, camera2D.Viewport.Y) * .5f) .ApplyScale(new Vector3D(1f, -1f, 1f)) .ApplyMatrix(camera2D.ViewMatrix) .Transposed; spriteBatch.Begin(transformMatrix: transformMatrix.ToXnaMatrix(), rasterizerState: rasterizerState); for (int i = 0; i < drawableSprites.Count; i++) drawableSprites[i].Draw(spriteBatch); spriteBatch.End(); } }