using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace LunaLightXMG { public class Camera2D { // Fields private readonly Viewport viewport; private float zoom; private float rotation; private Vector2 position; private Rectangle levelBounds; // Getters and setters public Vector2 Position { get => position; set => position = value; } public float Zoom { get => zoom; set => zoom = (int)Math.Floor(MathHelper.Clamp(value, 1f, 3f)); } public float Rotation { get => rotation; set => rotation = value; } // constructor public Camera2D(int width, int height) { this.viewport = new Viewport(0, 0, width, height); levelBounds = new Rectangle(0, 0, 320, 180); // Default zoom = 1f; rotation = 0f; position = Vector2.Zero; } public Matrix GetViewMatrix() { return Matrix.CreateTranslation(new Vector3(-position, 0f)) * Matrix.CreateRotationZ(rotation) * Matrix.CreateScale(zoom, zoom, 1f) * Matrix.CreateTranslation(new Vector3(viewport.Width * 0.5f, viewport.Height * 0.5f, 0f)); } public void SetLevelBounds(Rectangle bounds) { levelBounds = bounds; } public void Follow(Vector2 targetPostion) { // temp code Vector2 smoothPosition = Vector2.Lerp(position, targetPostion, 0.1f); position = smoothPosition; ClampToBounds(); } private void ClampToBounds() { // Calculate the cam's half viewport size var halfViewportWidth = viewport.Width * 0.5f / zoom; var halfViewportHeight = viewport.Height * 0.5f / zoom; // Clamp cam to level bounds float minX = levelBounds.Left + halfViewportWidth; float maxX = levelBounds.Right - halfViewportWidth; float minY = levelBounds.Top + halfViewportHeight; float maxY = levelBounds.Bottom - halfViewportHeight; // Set cam position within level bounds position.X = MathHelper.Clamp(position.X, minX, maxX); position.Y = MathHelper.Clamp(position.Y, minY, maxY); } } }