[libgdx] Parallax in a live wallpaper

I recently upgraded my code to use an OrthographicCamera. Prior to this, I had a working parallax effect. Generally, I achieved movement by actually shifting my sprites. I can no longer maintain this method due to other positional adjustments making it too intricate, so I opted to use the camera. Instead of shifting my sprites, I shift the camera.
This killed my implementation of the parallax. I’m trying to think of how to recreate it using the camera.

Here’s what I’m thinking:

Create an array of cameras.
Each physics update (before drawing), I update the camera array with each of my layers’ cams.
Iterate through array applying the current cam to the spritebatch and draw each layer.

Is this a viable approach?

Why would you move the camera?

Just move the furthest layers from the camera slower than the layers closest to the camera. Having a bunch of cameras would only decrease performance (maybe not by a lot at all, but its still silly to do it that way).

What is too intricate?

bunch of cameras doesnt decrease performance, they are just projection matrices and such you can set before rendering for free anyway.
I also have one camera for each layer.

I wouldnt move a layer back or to the front, because first of all you want 100% of the map to show up, left most when you are left and right most when you are at the right, and it would be tedious to get it exactly like that
and also the the sprites and/or tiles get smaller or bigger if you change the actual distance of the layer, which you probably dont want

to lessen the load a little bit, or just to avoid unnessecary redundancy, I made it so that each layer takes the normal camera unless a parallax camera is set.

Per frame (using SpriteCache here, you may use SpriteBatch or anything else of course)


		if (parallaxCamera != null)
		{
			updateParallaxCamera(camera);
			spriteCache.setProjectionMatrix(parallaxCamera.combined);
		}
		else
		{
			spriteCache.setProjectionMatrix(camera.combined);
		}
		
		spriteCache.begin();
			spriteCache.draw(cacheID);
		spriteCache.end();

	public void updateParallaxCamera(OrthographicCamera normalCamera)
	{
		parallaxCamera.zoom = normalCamera.zoom;
		
		minX = (Gdx.graphics.getWidth()*0.5f)*normalCamera.zoom;
		maxX = (baseWidth*TILESIZE)  - ((Gdx.graphics.getWidth()*0.5f)*normalCamera.zoom);
		minXpara = (Gdx.graphics.getWidth()*0.5f)*parallaxCamera.zoom;
		maxXpara = (width*TILESIZE)  - ((Gdx.graphics.getWidth()*0.5f)*parallaxCamera.zoom);

		minY = (Gdx.graphics.getHeight()*0.5f)*normalCamera.zoom;
		maxY = (baseHeight*TILESIZE)  - ((Gdx.graphics.getHeight()*0.5f)*normalCamera.zoom);
		minYpara = (Gdx.graphics.getHeight()*0.5f)*parallaxCamera.zoom;
		maxYpara = (height*TILESIZE)  - ((Gdx.graphics.getHeight()*0.5f)*parallaxCamera.zoom);
		
		parallaxCamera.position.x = minXpara + (((maxXpara-minXpara)/100f)*((100.0f/(maxX-minX))*(normalCamera.position.x - minX)));
		parallaxCamera.position.y = minYpara + (((maxYpara-minYpara)/100f)*((100.0f/(maxY-minY))*(normalCamera.position.y - minY)));
		
		parallaxCamera.update();
	}

I kinda calculated this percentage wise.
I think it doesnt yet work properly if you wanna have one layer zoomed and one not and so on, but I dont need that so I didnt bother fixing it; but it would be easy to do so.

Thank you. I got it working :slight_smile: