Smooth background scrolling - small freezes in a loop

Hi everyone. I am experiencing a problem with moving graphics. I thought that this is caused by the PC, but it isn’t.
I have tested it on CoreI5, 16GB Ram and 4GB graphics and on a laptop with IntelPentium, 2GB’s of ram and 512 graphics. It is still the same, totally the same on both devices.

Let’s start with an example here: http://www.kilobolt.com/day-5-background-and-sprites/unit-2-day-5-background-and-sprites
Source can be downloaded here: http://www.kilobolt.com/uploads/1/2/5/7/12571940/kiloboltgameday5.zip

Every game that I create has a small bug. I didn’t want to post mine, cause every of them has the same problem as in this above.
The problem: When I move the background (move the character) or make it moveable by itself infinitely it freezes by 1-2px every ~50-100 ms.
It is nearly unnoticable, but still is. As we all know, there is no place for bugs like this, even if they are that small.

When you download the source you have to look at the sky of the scrolling background and you will probably see, that mountains are freezing for a while for 1px. It’s really hard to discover, that’s why I didn’t post any video, cause it has to be seen live to notice.

I have already tried implementing FPS’s, already checked that this isn’t an error ‘when background changes for the second background’, cause it is happening every 50-100 ms and background changes every 2 seconds.

I think there is a problem with a size of the graphics. When robot is drawn (the character) it works smoothly, there is totally no freeze.
Background image is bigger and that’s why it may lagg, but I can’t even test it properly cause I don’t have an idea how.
I
If there is someone experienced that could look on this, download and try to explain, I would be grateful.
I don’t need any code, but a simple explanation why this is happening. Thank you very much!

Hello, can you show us a gif of what’s happening? I didn’t notice anything unusual.

Hi there !

I too experienced this.
Usually it is an issue within the method that process the rendering and/or the object update.
You could post your render method here so we can have a look to it.

For me, it was the java garbage collector that causes this micro-freeze.
I fixed this issue by looking carefully after object instantiation in the render loop.
Every temporary variable I use in the render loop is an attribute to the class that process the rendering.

could you just be experiencing vsync not being used?

Hi guys, thank you for all of your answers. Finally I’ve uploaded the video:

You can see that the character is moving smoothly, there is no freeze during all the game.
But when we look at the mountains, we can see a small freeze there.

Here are three main methods:

@Override
	public void run() {
		while (true) {
			robot.update();
			if (robot.isJumped()){
				currentSprite = characterJumped;
			}else if (robot.isJumped() == false && robot.isDucked() == false){
				currentSprite = character;
			}
			bg1.update();
			bg2.update();
			repaint();
			try {
				Thread.sleep(17);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void update(Graphics g) {
		if (image == null) {
			image = createImage(this.getWidth(), this.getHeight());
			second = image.getGraphics();
		}

		second.setColor(getBackground());
		second.fillRect(0, 0, getWidth(), getHeight());
		second.setColor(getForeground());
		paint(second);

		g.drawImage(image, 0, 0, this);

	}

	@Override
	public void paint(Graphics g) {
		g.drawImage(background, bg1.getBgX(), bg1.getBgY(), this);
		g.drawImage(background, bg2.getBgX(), bg2.getBgY(), this);
		g.drawImage(currentSprite, robot.getCenterX() - 61, robot.getCenterY() - 63, this);

	}

Can you show us the followings :
repaint();
robot.update();
bg1/bg2.update();

ROBOT UPDATE

public void update() {
		// Moves Character or Scrolls Background accordingly.

		if (speedX < 0) {
			centerX += speedX;
		}
		if (speedX == 0 || speedX < 0) {
			bg1.setSpeedX(0);
			bg2.setSpeedX(0);

		}
		if (centerX <= 200 && speedX > 0) {
			centerX += speedX;
		}
		if (speedX > 0 && centerX > 200){
			bg1.setSpeedX(-MOVESPEED);
			bg2.setSpeedX(-MOVESPEED);
		}

		// Updates Y Position
		centerY += speedY;
		if (centerY + speedY >= GROUND) {
			centerY = GROUND;
		}

		// Handles Jumping
		if (jumped == true) {
			speedY += 1;

			if (centerY + speedY >= GROUND) {
				centerY = GROUND;
				speedY = 0;
				jumped = false;
			}

		}

		// Prevents going beyond X coordinate of 0
		if (centerX + speedX <= 60) {
			centerX = 61;
		}
	}

BACKGROUND UPDATE (bg1 and bg2 are instances of the same class)

public void update() {
		bgX += speedX;

		if (bgX <= -2160){
			bgX += 4320;
		}
	}

As we can read on StackOverflow:

Difference between Paint() and Repaint() method

Paint():

This method holds instructions to paint this component. Actually, in Swing, you should change paintComponent() instead of paint(), as paint calls paintBorder(), paintComponent() and paintChildren(). You shouldn’t call this method directly, you should call repaint() instead.

Repaint():

This method can’t be overridden. It controls the update() -> paint() cycle. You should call this method to get a component to repaint itself. If you have done anything to change the look of the component, but not it’s size ( like changing color, animating, etc. ) then call this method.

So repaint() just calls paint()

It’s strange…

Maybe you could download the source and try to open the app on your PC? Maybe it’s really ‘v-sync’ or something? I don’t know…

Yeah, I’ll do so this evening.

Bump? Someone? :frowning:

Hi,

I’ve been testing this project, but I can’t really say if I saw flickering… Maybe…
One thing I was thinking of : you could take in consideration the lapse of time between 2 renders/updates :
For instance, your background update method :


public void update() {
      bgX += speedX;

      if (bgX <= -2160){
         bgX += 4320;
      }
   }

You could give as a parameter the time passed since your last update :


public void update(float deltaTime) {
      bgX += speedX * deltaTime;

      if (bgX <= -2160){
         bgX += 4320;
      }
   }

Maybe this will smooth your render ?