Contact Home

# How to Create a Parallax Effect in Monogame

## Posted on: August 5th, 2013 by admin 5 Comments

This post will explain how to create a parallax effect in Monogame. First, take a look at the demo video to see what we will be doing:

This effect can be accomplished quite easily in Monogame. We create a Background class, so that we can layer multiple backgrounds together. This class will keep track of individual background images, speed, and zoom level.

Have a look at the documented code below:
```using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace MonogameParallax
{
public class Background
{
private Texture2D Texture;      //The image to use
private Vector2 Offset;         //Offset to start drawing our image
public Vector2 Speed;           //Speed of movement of our parallax effect
public float Zoom;              //Zoom level of our image

private Viewport Viewport;      //Our game viewport

//Calculate Rectangle dimensions, based on offset/viewport/zoom values
private Rectangle Rectangle
{
get { return new Rectangle((int)(Offset.X), (int)(Offset.Y), (int)(Viewport.Width / Zoom), (int)(Viewport.Height / Zoom)); }
}

public Background(Texture2D texture, Vector2 speed, float zoom)
{
Texture = texture;
Offset = Vector2.Zero;
Speed = speed;
Zoom = zoom;
}

public void Update(GameTime gametime, Vector2 direction, Viewport viewport)
{
float elapsed = (float)gametime.ElapsedGameTime.TotalSeconds;

//Store the viewport
Viewport = viewport;

//Calculate the distance to move our image, based on speed
Vector2 distance = direction * Speed * elapsed;

//Update our offset
Offset += distance;
}

public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Texture, new Vector2(Viewport.X, Viewport.Y), Rectangle, Color.White, 0, Vector2.Zero, Zoom, SpriteEffects.None, 1);
}
}
}```
In order for these Backgrounds to fill our entire viewport area, they need to be drawn using a LinearWrap SamplerState. The SampleState is specified during our SpriteBatch initialization.

Since the background textures are drawn to wrap, we create the illusion of moving the image by setting an Offset point to begin drawing our texture. This offset is manipulated by a Direction vector during the Update call.

I have provided a main Game class to demonstrate an implementation of this technique:
```using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Input;

namespace MonogameParallax
{
public class MonogameParallax : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
List<Background> Backgrounds;

public MonogameParallax() : base()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

protected override void Initialize()
{
base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);

//Load the background images
Backgrounds = new List<Background>();
}

protected override void UnloadContent()
{
}

protected override void Update(GameTime gameTime)
{
KeyboardState kbState = Keyboard.GetState();

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();

//Get directional vector based on keyboard input
Vector2 direction = Vector2.Zero;
if (kbState.IsKeyDown(Keys.Up))
direction = new Vector2(0, -1);
else if (kbState.IsKeyDown(Keys.Down))
direction = new Vector2(0, 1);
if (kbState.IsKeyDown(Keys.Left))
direction += new Vector2(-1, 0);
else if (kbState.IsKeyDown(Keys.Right))
direction += new Vector2(1, 0);

//Update backgrounds
foreach (Background bg in Backgrounds)
bg.Update(gameTime, direction, GraphicsDevice.Viewport);

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

//Draw our parallax backgrounds, using a Linear Wrap
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null);
foreach (Background bg in Backgrounds)
bg.Draw(spriteBatch);
spriteBatch.End();

base.Draw(gameTime);
}
}
}```

Feel free to download the source code.

Contact me with any questions or comments.

# 5 Responses

## admincommented on April 30, 2016 at 2:57 pm

Hey I fixed the link. Thanks for bringing this to my attention.

## Benoit Archambaultcommented on November 20, 2016 at 7:48 am

xnb files are not included… don’t know if this was on purpose?

## seppe geerinckxcommented on November 30, 2016 at 2:14 pm

how to only scroll trough the background horizontal and not vertical please could you explain that to me

## joshua R Holdencommented on April 10, 2017 at 10:30 pm

//if (kbState.IsKeyDown(Keys.Up))
//              direction = new Vector2(0, -1);
//          else if (kbState.IsKeyDown(Keys.Down))
//               direction = new Vector2(0, 1);