4

I'm making a game in LibGDX. I have 4 textures as a parallax background and some obstacles (one in the upper part and others in the bottom part of the screen), this is the movement part:

//Parallax    
if (bckgndmiddle_x <= -Const.VIEWPORT_W*2+(game_speed*delta)/2) bckgndmiddle_x=-(game_speed*delta)/2; else bckgndmiddle_x-=(game_speed*delta)/2;
    if (bckgndfar_x <= -Const.VIEWPORT_W*2+(game_speed*delta)/5)      bckgndfar_x=-(game_speed*delta)/5; else bckgndfar_x-=(game_speed*delta)/5;

    for (Obstacle obst:obstacles) {
        obst.update(game_speed*delta);
    }

    //End Main game loop

    player.update();
    game.batch.begin();
    game.batch.draw(wall, bckgndfar_x,floor.getRegionHeight()+100);
    game.batch.draw(wall, bckgndfar_x+wall.getRegionWidth(),floor.getRegionHeight()+100);
    game.batch.draw(bot_furniture, bckgndmiddle_x,floor.getRegionHeight());
    game.batch.draw(bot_furniture, bckgndmiddle_x+bot_furniture.getRegionWidth(),floor.getRegionHeight());
    game.batch.draw(floor, bckgndmiddle_x,0);
    game.batch.draw(floor, bckgndmiddle_x+floor.getRegionWidth(),0);
    game.batch.draw(ceiling, bckgndfar_x,Const.VIEWPORT_H-ceiling.getRegionHeight());
    game.batch.draw(ceiling, bckgndfar_x+ceiling.getRegionWidth(),Const.VIEWPORT_H-ceiling.getRegionHeight());

The obstacle update method is just x-= speed; as speed is the parameter received

The problem is that from time to time the textures wiggles strange, like if the device cannot handle the game and freezes for a split second.

Any clue why is this happening?

EDIT

What happens is that the textures stutters from time to time (I'm Spanish and I didn't know that word)

I think that it must be something related to the second image of each part of the background, that adding of the width. Like it adds the width, but sometimes it is too much because of a drop of fps (like 1 or 2 fps) and the next time it "moves" back to the good position because fps are back to normal.

EDIT 2 I tried it without the obstacles and it still stutters, I tried it again with the obstacles and without the background and it doesnt, so it must be something with what I said in the first edit.

BTW, the FPS drop is less than 1 (checked)

I have just tried to draw a entire background image (no parallax) and still the same issue.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
J. Arenas
  • 493
  • 1
  • 9
  • 23
  • Sounds like a garbage collection issue. Are you allocating a lot of objects in the render loop? – Tenfour04 Feb 23 '15 at 05:49
  • I don't think it is garbage collection, I don't use that much objects. I think that it has something to do with the second draw of each background with the assing of the width that it dont have any aplying of the delta, but I tried some things and It still doesn`t work – J. Arenas Feb 23 '15 at 07:54
  • What kind of framerate is this running at? It seems a little unlikely that a drop of 1 fps would produce visible stuttering – rbennett485 Feb 23 '15 at 14:11
  • @rbennett485 It is running at 60fps. In log the minimum value is about 59.2 to 59.9 fps – J. Arenas Feb 23 '15 at 14:22

2 Answers2

2

I see one possible reason that has nothing to do with FPS drops:

Here's your first line, separated out for legibility:

if (bckgndmiddle_x <= -Const.VIEWPORT_W*2+(game_speed*delta)/2) 
    bckgndmiddle_x = -(game_speed*delta)/2; 
else 
    bckgndmiddle_x -= (game_speed*delta)/2;

Usually, the else statement is used to move the background at a constant speed. But whenever it gets to the if statement, the position is explicitly set without regard to its previous position, so the movement will not be smooth. You need to move it to a position where it looks like it has moved exactly -(game_speed*delta)/2 from its previous position.

One way to do this is to always move the object with speed, and shift it forward by the texture's width only when necessary as a correction. For example, assuming you are keeping the bottom left of the screen at (0, 0)::

float midWidth = floor.getRegionWidth();

bckgndmiddle_x -= game_speed*delta/2; //Always move it at constant speed.
if (bckgndmiddle_x + 2*midWidth < Const.VIEWPORT_W) //Right edge starting to show. 
    bckgndmiddle_x += midWidth; // Shift it exactly by its width so the jump is undetectable

The 2* above is because I'm assuming from your other code that you are actually drawing two copies of the background texture side by side. If you were drawing a single, wider texture that's wider than the viewport width constant, then you'd remove the 2*.

This same issue applies of course to your second line of code as well, where you are setting the far background displacement.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • The 2* is because the texture is double the camera width. I am still drawing two copies, so when the first has just disappeared from the screen it is moved its length to match the end of the other one. I will give it a try as it makes sense to me, I will reply ASAP – J. Arenas Feb 23 '15 at 17:30
  • I've donde that but still same behaviour. I noticed that it occurs randomly, not necessary when it has to correct the position. – J. Arenas Feb 23 '15 at 17:55
0

Had similar issue, fixed by disabling vsync

    LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
    config.vSyncEnabled = false; 
Yurij Skalskyy
  • 111
  • 1
  • 5