1
\$\begingroup\$

I started working on my first proper game but reached a problem straight away. In short I have a game that runs most of the time at 60 fps. ( I am using Libgdx a popular Java framework) but my game object which has a constant velocity and is multiplied by delta, is not moving smoothly. I have tried turning vsync on and off but that does not help. My speed variable is -100, and it is only moving vertically downwards so it is pretty clear if it is moving jerkily or not. Here is my quite simple code:

public class Ball extends AbstractGameObject {

private TextureRegion tex = Assets.instance.ball;
private float speed;

public Drop(Vector2 pos, float speed) {
    super(pos);
    this.speed = speed;

    width = 17;
    height = 32;

    type = Type.Ball;

}

@Override
public void update(float delta) {
    pos.y = pos.y + (speed * delta);
    rect.set(pos.x,pos.y,width,height);

}

@Override
public void render(SpriteBatch sb) {

    sb.draw(tex, pos.x, pos.y, width, height);

}

public float getSpeed() {
    return speed;
}

public void setSpeed(float speed) {
    this.speed = speed;
}

}

It was previously of my understanding that by multiplying by the elapsed seconds since the last frame, it would guarentee smooth movement. Is thing wrong? If so, any suggestions on how to make it smoother?

\$\endgroup\$
  • \$\begingroup\$ The problem is present when the speed is both low and high, more so when the speed is high. As for the elapsed time libgdx handles it when calling a method called getDeltaTime();. Usually it returns a value in a range from 0.016 to 0.02. I also made sure that the a delta value is clamped so it doesn't go higher than 0.1 \$\endgroup\$ – TheQuantumGamer Jan 21 '15 at 18:17
  • \$\begingroup\$ Wait a minute... with v-sync on, it gives you other values than 0,016666667? Also, make sure there isnt some integer interfering in any part of movement (or similar precision loss). \$\endgroup\$ – wondra Jan 21 '15 at 18:26
  • \$\begingroup\$ I checked and yeah even with v-sync on it gives me a range values that are pretty close to 0.016666667. Also I made sure that no integer(or anything else) is interfering with my movement. \$\endgroup\$ – TheQuantumGamer Jan 21 '15 at 18:33
  • 1
    \$\begingroup\$ You can try following: replace (speed * delta); with a constant, for example 1,666667f. If the problems persist - the gameloop is not the thing to blame. (keep v-sync still on!) Also, is pos.Y integer or float? \$\endgroup\$ – wondra Jan 21 '15 at 18:36
  • \$\begingroup\$ I just tried it and sadly its the same; still jerky. \$\endgroup\$ – TheQuantumGamer Jan 21 '15 at 18:40
1
\$\begingroup\$

This could be due to double & triple buffering and processing spikes, probably due to GC.

  • frame 0, delta 0, display buffer 0, draw buffer 1
  • time passed: 0.016
  • frame 1, delta 0.016, display buffer 1, draw buffer 0 (at +0.016)
  • time passed: 0.016
  • frame 2, delta 0.016, display buffer 0, draw buffer 1 (at +0.016)
  • time passed: 0.032 hickup
  • frame 3, delta 0.032, display buffer 1 (drawn for +0.016 but it's been 0.032ms in reality), draw buffer 1 (at +0.032)
  • time passed: 0.016
  • frame 4, delta 0.016, display buffer 0 (drawn for +0.032 but its been 0.016 in reality), draw buffer 1 (at +0.016)

Because the delta is the one between the previous two frames there is always a reaction delay in your frame rate compensation which cause the perceived hitches.

Delta time works when the frame rate drops in a smooth manner over a long period of time but causes extra-jerky movements when there are random spikes.

Note also that moving by -100 * 0.016 gives you a movement of 1.6 pixels per frame causing your sprite to move 1 pixel, 2 pixels, 1 pixel, 2 pixels, 2 pixels, 1 pixel...

Try changing your speed to -61 instead, this will give you 1.016666687 pixel per frame which might help.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ so what's the best way to fix this? Use a non GC language such as C++? From what I've read and understand above, Java GC will always cause these unwanted problems? Or maybe design all code to minimise need for garbage collection? E.g. use global static variables where possible. \$\endgroup\$ – Pixel Jul 15 '18 at 8:34
  • \$\begingroup\$ There isn't a perfect solution. In this case the characters movement is rounded to the nearest pixel. One way to improve the situation is to draw sub-pixels so the graphics aren't rounded to the nearest pixel but that can make the graphics look "blurry" because now they're not aligned to exact pixels, or make sure the character usually moves at an integer multiple of pixels. \$\endgroup\$ – Stephane Hockenhull Jul 21 '18 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.