Parallax background jerking - LibGDX

I have a player that can move any direction on a 2D plane, and behind the player are two background images that move at different speeds to create a parallax effect. This seems to happen randomly, but there are times during movement when the background images jerk. It’s very noticeable because the backgrounds look extremely smooth up until a random jerk motion. I can’t replicate the problem besides just randomly moving around.

This is the code I’m using to update my backgrounds positions:


        backgroundSprite1.draw(batch);                          
        backgroundSprite2.draw(batch, 0.2f);
        backgroundSprite1.setX(-Gdx.graphics.getWidth() / 2f + player.getPosition().x / 1.1f);
        backgroundSprite1.setY(-Gdx.graphics.getHeight() / 2f + player.getPosition().y / 1.1f);
        backgroundSprite2.setX(-Gdx.graphics.getWidth() / 2f + player.getPosition().x / 1.025f);
        backgroundSprite2.setY(-Gdx.graphics.getHeight() / 2f + player.getPosition().y / 1.025f);

I’ve read that this may happen during an expensive calculation, however my application so far is pretty basic. I only started having these issues up until making a parallax effect which is meant to be very slow moving.

Has anyone run into this similar issue, or could offer advice?

Hey,

So without knowing too much about what the rest of the code does, here’s a couple of things that I’ve run into when working on my project that also uses LibGDX:

  1. It’s possible that you might be running into “texture swapping” issues.

When drawing images to the screen, any time something comes from a different source than the batch is currently using, it has to swap over to the other texture and then back again.

This means, if both backgrounds, and the character sprite are on different textures (sprite sheets, images etc) then each time it draws them, you’re constantly swapping which uses up processing time.

Now, I’ve personally only recently ran into this issue when running on lower end Android devices, but was most certainly an issue. So, this may or may not be a concern for you right now, but maybe later.

  1. Garbage collection

It’s possible that somewhere else in the code you are generating a large number of objects that cause the GC to kick off and do cleanup. (possibly Vector2 or some other object used for calculations)

Sometimes, depending on what’s needed, this can cause an interruption in screen drawing. You might want to look around to see if you are creating anything in large numbers and consider using LibGDX Pool’s or revisit the need of the objects.

  1. I see in the code you are drawing, then changing the position of the sprites.

I’m not sure if this will matter or not, but that would suggest that you are setting the new position after it’s drawn (to be picked up next loop/draw). You could try moving the position assignment before the draw methods to ensure you have everything in sync. Again, just a guess, and may not make any difference at all.

Hope this helps, if not, hopefully for future issues you may run into. Good luck!

Do you have something like a gameScreen that implements Screen?

Then there’s a render(float delta) method. Is that where you put your game logic?

EDIT: I’ve only started a libGDX project within the last week but I think this is how the game is supposed to be structured. Both logic and draw calls go under this render Method.

So…

Read this

and this

@NetprogsGames
Thanks for the reply! I couldn’t find anything while inspecting my code with your recommendations in mind, but they are good to know. I’ve also changed my code per your third note. My situation is inspiring me to find a tool that will check which pieces of code take up the most time. I’ll report back with what I find.

@ndnwarrior15
Yes that’s exactly the setup I have. I have a game screen that implements Screen, and within that classes render method I call appropriate render/update methods:


    World world;                                  // Handles object creation of all entities
    Renderer renderer;                         // Handles the graphical rendering of all entities

    @Override
    public void render(float delta) {
        world.update();                                     
        renderer.render();      
    }

World handles object creation and takes care of actions such as updating positions and collision detection(checking if bounds overlap). Renderer polls all the objects created from world, and handles loading textures and particle effects for these objects.

Nothing is glaringly sticking out, and I have tried removing logic in order to see what is causing my problem. I know for a fact it has to do with logic I’ve added of the past few weeks, because earlier commits from a few weeks ago don’t have this issue. Looking forward to finding it…

There are other tools I use also, but I find “Java VisualVM” (which should be in your bin directory of your JDK I think) works quite well overall. Takes some getting used to, but might give you some area’s to look at.

Good luck on the search, I’m sure you’ll find it!

How are you updating the player position each frame? Is it x += someVariable OR x += someVariable * delta ?

My player uses a Vector2 position variable and a Vector2 velocity variable, which is updated within it’s own player classes update() method:

position.add(velocity.cpy().scl(Gdx.graphics.getDeltaTime() * Constant.SPEED));

SPEED is a constant that is different for different kinds of players. The players position is updated via the logic above, combined with conditional statements that determine which way the player is moving, which adds/subtracts from the players velocity.x/y accordingly.

Are you suggesting that using getDeltaTime may be a bad idea?

This is just my experience so take it or leave it. Also I edited an earlier post and added some links, did you read those?

When I first started making games I made like 5 or so that used the deltaTime thing and had this hiccup/jerk that you are describing. After reading that dewitters game loop article I switched to fixing the time step altogether and over the course of hours and hours of testing my game on both android and desktop I haven’t seen it hiccup once.

I’m betting others have been able to get a game to work using the built in deltaTime thing with libGDX but I couldn’t. There was always something jittering around so I won’t go back to using it. Instead, fixing the time step and interpolating the graphics has worked for me.

Upon further reading I understand why you posted those articles. Those were great reads and may very much be my issue. Even if it’s not my issue I think it’s a good idea to begin implementing the interpolation of my models. I’m very sure that would fix my issue, though I thought it would be more trivial in all honestly.

I greatly appreciate it!