using Microsoft.Xna.Framework; using System; // Good background reading, eventually: // https://gamasutra.com/blogs/ItayKeren/20150511/243083/Scroll_Back_The_Theory_and_Practice_of_Cameras_in_SideScrollers.php namespace SemiColinGames { public class Camera { // Screen size in pixels is 1920x1080 divided by 4. private Rectangle bbox = new Rectangle(0, 0, 1920 / 4, 1080 / 4); public int Width { get => bbox.Width; } public int Height { get => bbox.Height; } public int Left { get => bbox.Left; } public int Top { get => bbox.Top; } public int Bottom { get => bbox.Bottom; } public Point HalfSize { get => new Point(Width / 2, Height / 2); } private readonly Random random = new Random(); private float shakeTime = 0.0f; public Matrix Projection { get => Matrix.CreateOrthographicOffCenter(Left, Left + Width, Height + Top, Top, -1, 1); } public void Update(float modelTime, Player player, int worldWidth, int worldHeight) { Vector2 pos = player.Position; float xDiff = pos.X - bbox.Center.X; float yDiff = pos.Y - bbox.Center.Y; if (Math.Abs(xDiff) > 16) { bbox.Offset((int) (xDiff * 0.1), 0); } if (player.StandingOnGround) { bbox.Offset(0, (int) (yDiff * 0.1)); } if (yDiff > 16) { bbox.Offset(0, (int) (yDiff * 0.2)); } if (bbox.Left < 0) { bbox.Offset(-bbox.Left, 0); } if (bbox.Right > worldWidth) { bbox.Offset(worldWidth - bbox.Right, 0); } if (bbox.Top < 0) { bbox.Offset(0, -bbox.Top); } if (bbox.Bottom > worldHeight) { bbox.Offset(0, worldHeight - bbox.Bottom); } if (shakeTime > 0) { shakeTime -= modelTime; int x = random.Next(-4, 5); int y = random.Next(-4, 5); bbox.Offset(x, y); } Debug.AddToast($"p: {pos.X}, {pos.Y} c: {bbox.Center.X}"); } public void Shake() { shakeTime = 0.3f; } } }