[SOLVED] Parallax Scrolling

Hello All. I have been making various demos using Monogame.Extended so that I can get all the fundamental building blocks working before making my game, and I would like to accomplish parallax scrolling of a Tiled TMX Map. I have a working solution, but am not sure if there is a better way.

I have a 2 layered map, and I want the background layer to scroll at half the speed. So my solution was to make 2 Camera2Ds, one for the foreground layer of the map, and one for the background layer of the map. On the Update() function, I adjusted the background camera position according to the position of the foreground camera like so:

backgroundCamera.Position = new Vector2(foregroundCamera.Position.X * 0.5f, foregroundCamera.Position.Y * 0.5f);

Then on the Draw() function, I call Draw on both cameras, by drawing specific layers, rather than the entire map, like this:

mapRenderer.Draw(map.GetLayer("Background"), backgroundCamera.GetViewMatrix());//draw background layer
mapRenderer.Draw(map.GetLayer("Foreground"), foregroundCamera.GetViewMatrix());//draw foreground layer

My question is, is there a way to adjust the background layer position, so that I only need a single camera to render both layers, but with the background layer re-positioned for parallax? Couldn’t there be a settable offset for the tile layer perhaps?

Thank you for reading.

mapRenderer.Draw takes a matrix as the second parameter. You can modify that matrix to shift the layer, without changing your camera. Just multiply the view matrix from your camera with a translation matrix (Matrix.CreateTranslation) before you pass it to mapRenderer.Draw.

Matrix layerMat = Matrix.CreateTranslation(shiftX, shiftY, shiftZ) * backgroundCamera.GetViewMatrix();
mapRenderer.Draw(map.GetLayer("Background"), layerMat );
1 Like

Wow! Thank you so much! Not only did your example allow me to eliminate the other cameras, but while I was poking around in the Camera2D class, I saw where the camera has a method by which it can return a “Parallax” Matrix by passing in a parallax factor in the form of a Vector 2. This handles the parallax matrix transforms for my different layers based on the Camera position:

Matrix midLayerMatrix = camera.GetViewMatrix(parallaxFactor);//Parallax Factor is a Vector2(0.5f, 0.5f) mapRenderer.Draw(map.GetLayer("MidLayer"), midLayerMatrix);//draws parallax layer as adjusted mapRenderer.Draw(map.GetLayer("Foreground"), camera.GetViewMatrix());//draw foreground layer
Thank you again!!

For those interested, here is a link to my test project that loads a TMX Tiled Map, and demonstrates parallax scrolling: