105 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Microsoft.Xna.Framework;
 | 
						|
using Microsoft.Xna.Framework.Graphics;
 | 
						|
 | 
						|
using Engine.Core;
 | 
						|
 | 
						|
namespace Engine.Integration.MonoGame;
 | 
						|
 | 
						|
public class MonoGameCamera2D : Behaviour, ICamera2D, IFirstFrameUpdate, ILastFrameUpdate, IPreDraw
 | 
						|
{
 | 
						|
    public Event<MonoGameCamera2D> OnMatrixTransformChanged { get; } = new();
 | 
						|
    public Event<MonoGameCamera2D> OnViewportChanged { get; } = new();
 | 
						|
    public Event<MonoGameCamera2D> OnZoomChanged { get; } = new();
 | 
						|
 | 
						|
    private Matrix _matrixTransform = Matrix.Identity;
 | 
						|
 | 
						|
    private Viewport _viewport = default;
 | 
						|
    private float _zoom = 1f;
 | 
						|
 | 
						|
    public GraphicsDeviceManager Graphics { get; private set; } = null!;
 | 
						|
    public ITransform2D Transform { get; private set; } = null!;
 | 
						|
 | 
						|
    public Matrix MatrixTransform
 | 
						|
    {
 | 
						|
        get => _matrixTransform;
 | 
						|
        set
 | 
						|
        {
 | 
						|
            if (_matrixTransform == value)
 | 
						|
                return;
 | 
						|
 | 
						|
            _matrixTransform = value;
 | 
						|
            OnMatrixTransformChanged.Invoke(this);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public Vector2D Position
 | 
						|
    {
 | 
						|
        get => Transform.Position;
 | 
						|
        set => Transform.Position = value;
 | 
						|
    }
 | 
						|
 | 
						|
    public Viewport Viewport
 | 
						|
    {
 | 
						|
        get => _viewport;
 | 
						|
        set
 | 
						|
        {
 | 
						|
            if (_viewport.Equals(value))
 | 
						|
                return;
 | 
						|
 | 
						|
            _viewport = value;
 | 
						|
            OnViewportChanged.Invoke(this);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public float Zoom
 | 
						|
    {
 | 
						|
        get => _zoom;
 | 
						|
        set
 | 
						|
        {
 | 
						|
            float newValue = Math.Max(0.1f, value);
 | 
						|
 | 
						|
            if (_zoom == newValue)
 | 
						|
                return;
 | 
						|
 | 
						|
            _zoom = newValue;
 | 
						|
            OnZoomChanged.Invoke(this);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public float Rotation
 | 
						|
    {
 | 
						|
        get => Transform.Rotation;
 | 
						|
        set => Transform.Rotation = value;
 | 
						|
    }
 | 
						|
 | 
						|
    // TODO This causes delay since OnPreDraw calls assuming this is called in in Update 
 | 
						|
    public Vector2D ScreenToWorldPosition(Vector2D screenPosition)
 | 
						|
    {
 | 
						|
        Vector2D worldPosition = Vector2.Transform(screenPosition.ToVector2(), Matrix.Invert(MatrixTransform)).ToVector2D();
 | 
						|
        return worldPosition.Scale(EngineConverterExtensions.screenScale);
 | 
						|
    }
 | 
						|
    public Vector2D WorldToScreenPosition(Vector2D worldPosition)
 | 
						|
    {
 | 
						|
        Vector2D screenPosition = Vector2.Transform(worldPosition.ToVector2(), MatrixTransform).ToVector2D();
 | 
						|
        return screenPosition.Scale(EngineConverterExtensions.screenScale);
 | 
						|
    }
 | 
						|
 | 
						|
    public void LastActiveFrame() => Transform = null!;
 | 
						|
    public void FirstActiveFrame()
 | 
						|
    {
 | 
						|
        Graphics = BehaviourController.UniverseObject.Universe.FindRequiredBehaviour<MonoGameWindowContainer>().Window.Graphics;
 | 
						|
        Viewport = Graphics.GraphicsDevice.Viewport;
 | 
						|
        Transform = BehaviourController.GetRequiredBehaviour<ITransform2D>();
 | 
						|
    }
 | 
						|
 | 
						|
    public void PreDraw()
 | 
						|
    {
 | 
						|
        MatrixTransform =
 | 
						|
            Matrix.CreateTranslation(new Vector3(-Position.X, Position.Y, 0f)) *
 | 
						|
            Matrix.CreateRotationZ(Rotation * Math.DegreeToRadian) *
 | 
						|
            Matrix.CreateScale(Transform.Scale.X.Max(Transform.Scale.Y)) *
 | 
						|
            Matrix.CreateScale(Zoom) *
 | 
						|
            Matrix.CreateTranslation(new Vector3(_viewport.Width * .5f, _viewport.Height * .5f, 0f));
 | 
						|
    }
 | 
						|
}
 |