diff options
| author | hazel <hazel@hazelthats.me> | 2026-01-26 22:04:39 +0100 |
|---|---|---|
| committer | hazel <hazel@hazelthats.me> | 2026-01-26 22:04:39 +0100 |
| commit | 567c422f8cd42eba2437f9a8c2522716a1649be7 (patch) | |
| tree | 93c5b296f3b7c14b626d0aadf5cad37764c41c74 /source/graphics/Camera2D.cs | |
| download | celesteia-567c422f8cd42eba2437f9a8c2522716a1649be7.tar.gz celesteia-567c422f8cd42eba2437f9a8c2522716a1649be7.tar.bz2 celesteia-567c422f8cd42eba2437f9a8c2522716a1649be7.zip | |
celesteia archive, last updated april 9th 2024
Signed-off-by: hazel <hazel@hazelthats.me>
Diffstat (limited to 'source/graphics/Camera2D.cs')
| -rw-r--r-- | source/graphics/Camera2D.cs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/source/graphics/Camera2D.cs b/source/graphics/Camera2D.cs new file mode 100644 index 0000000..1bae764 --- /dev/null +++ b/source/graphics/Camera2D.cs @@ -0,0 +1,63 @@ +using System; +using Celesteia.Resources; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace Celesteia.Graphics { + public class Camera2D { + private GraphicsDevice _graphicsDevice; + + // Viewport macros. + private int ViewportX => _graphicsDevice.Viewport.X; + private int ViewportY => _graphicsDevice.Viewport.Y; + private int ViewportWidth => _graphicsDevice.Viewport.Width; + private int ViewportHeight => _graphicsDevice.Viewport.Height; + + private int _zoom = 0; + public int ScaledZoom { get; private set; } = 0; + // The zoom value of the camera. + public int Zoom { + get { return _zoom; } + set { + _zoom = MathHelper.Clamp(value, 1, 8); + ScaledZoom = _zoom * ResourceManager.INVERSE_SPRITE_SCALING; + } + } + + public Camera2D(GraphicsDevice graphicsDevice) { + _graphicsDevice = graphicsDevice; + Zoom = 2; + } + + // The camera's center. + public Vector2 Center = Vector2.Zero; + + private float _rotation; + // The rotation applied to the camera. + public float Rotation { + get { return _rotation; } + set { _rotation = value % 360f; } + } + + /* + Creates a matrix with the following steps: + - Create a translation to match (0, 0) to the center point of the camera. + - Apply Z rotation. + - Scale according to zoom value and inverse sprite scaling. + - Always round the viewport width and height to prevent half-pixel rounding issues. + */ + private float maxScale = 0f; + public Matrix GetViewMatrix() { + maxScale = MathF.Max(MathF.Ceiling(ViewportWidth / 1920f), MathF.Ceiling(ViewportHeight / 1080f)); + return Matrix.CreateTranslation(-Center.X, -Center.Y, 0f) * + Matrix.CreateRotationZ(Rotation) * + Matrix.CreateScale(ScaledZoom, ScaledZoom, 1f) * + Matrix.CreateScale(maxScale, maxScale, 1f) * + Matrix.CreateTranslation(ViewportWidth / 2f, ViewportHeight / 2f, 0f); + } + + // Transform the viewport relative mouse position to the inverse view matrix to get the pointer's position in the world. + public Vector2 ScreenToWorld(Point point) + => Vector2.Transform(new Vector2(point.X - ViewportX, point.Y - ViewportY), Matrix.Invert(GetViewMatrix())); + } +}
\ No newline at end of file |
