How to create a custom 2D camera in MonoGame



Introduction

This article will teach you how to add a basic camera to your MonoGame 2D project.



The Camera class

First we need to create a class that holds all the functions we will need to create and control a new Matrix for our 2D game.



using Microsoft.Xna.Framework;

class Camera
{

	// Matrix is referenced by the SpriteBatch when drawing
	// Used to position, scale and rotate all the sprites attached to that SpriteBatch
	private Matrix _matrix = Matrix.CreateTranslation(0,0,0);

	// Position for the Matrix
	private Vector2 _position;

	// Zoom scale for the Matrix
	private float _zoom;

	public Camera() {
		// Setting a default zoom scale of 1 - this is the SpriteBatch default
		this._zoom = 1;
	}

	// Allows us to get the Matrix
	public Matrix getMatrix() {
		return _matrix;
	}

	// Private function used to refresh the matrix calculations
	// whenever the position or scale is changed
	private void setMatrix() {
		this._matrix = Matrix.CreateTranslation(this._position.X, this._position.Y, 0) * Matrix.CreateScale(new Vector3(this._zoom, this._zoom, 1));
	}

	// Pass in an X and or Y value to be added to the Matrix current position
	public void adjustPosition(float x, float y) {
		this._position = this._position + new Vector2(x , y);
		this.setMatrix();
	}

	// Pass in a zoom value in order to alter the current zoom level
	public void adjustZoom(float zoom)
	{
		this._zoom = this._zoom + zoom;
		this.setMatrix();
	}
}
 


How to use the Camera class

Once the Camera class is created, we can go ahead and use it like so.



 public class Game1 : Game
 {
	...
	
	// Creating an instance of our Camera class
	Camera _camera = new Camera();
	
	
	protected override void Draw(GameTime gameTime)
	{
		...
		
		// Passing our Matrix from our _camera (Camera) into the SpriteBatch Begin function
		_spriteBatch.Begin(transformMatrix:this._camera.getMatrix());
	}
 }
 


Camera Controls

Once the Camera is set up to work with your SpriteBatch, you can control it by altering the values in the Camera class.

Here I will show one way of doing that using keyboard controls.



  public class Game1 : Game
 {
	...
	
	protected override void Update(GameTime gameTime)
	{
		...
		
		// Camera moves right, sprites move left
		// -1 from the X coordinate
		if (keyState.IsKeyDown(Keys.NumPad6))
		{
			this._camera.adjustPosition(-1, 0);
		}

		// Camera moves left, sprites move right
		// +1 to the X coordinate
		if (keyState.IsKeyDown(Keys.NumPad4))
		{
			this._camera.adjustPosition(1, 0);
		}

		// Camera moves down, sprites move up
		// -1 from the Y coordinate
		if (keyState.IsKeyDown(Keys.NumPad2))
		{
			this._camera.adjustPosition(0, -1);
		}

		// Camera moves up, sprites move down
		// +1 to the Y coordinate
		if (keyState.IsKeyDown(Keys.NumPad8))
		{
			this._camera.adjustPosition(0, 1);
		}

		// Increases the zoom value by 0.1f
		// Makes sprites larger
		if (keyState.IsKeyDown(Keys.Add))
		{
			this._camera.adjustZoom(0.1f);
		}

		// Decreases the zoom value by 0.1f
		// Makes sprites smaller
		if (keyState.IsKeyDown(Keys.Subtract))
		{
			this._camera.adjustZoom(-0.1f);
		}
	}
 }