Render stuttering

I have been searching the whole internet for a working fix, it helped with most of the stuttering, but every now and then I still feel it is not smooth. I’m pretty new to actual game programming in Java, and I really hope anyone can help me with this problem.

The code I have is:

package com.game;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class Main implements Runnable {
	
	public final static int GAME_WIDTH = 640, GAME_HEIGHT = 480;
	
	BufferedImage tile;
	//BufferedImage tile = new BufferedImage(48, 48, BufferedImage.TYPE_INT_RGB);
	
	int[] x = new int[1000];
	int[] y = new int[1000];
	
	final int SIZE = 48;
	
	Canvas canvas;
	
	public void load() {
		try {
			tile = ImageIO.read(new File("./grass.png"));
		} catch(IOException e) {
			
		}
		
		int width = 0, height = 0;
		for(int i = 0; i < x.length; i++) {
			x[i] = width*SIZE;
			y[i] = height*SIZE;
			width++;
			if(width > 80) {
				width = 0;
				height++;
			}
		}
	}
	
	public Main() {
		load();
		
		canvas = new Canvas();
		
		JFrame frame = new JFrame("Game");
		frame.setResizable(false);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLayout(new BorderLayout());
		frame.setSize(GAME_WIDTH, GAME_HEIGHT);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		
		frame.add(canvas);
		

		(new Thread(this)).start();
		
	}
	
	public static void main(String[] args) {
		new Main();
	}
	
	int offsetX = -200;
	
	public void tick() {
		int speed = -3;
		
		offsetX += speed;
	}
	
	public BufferedImage image = new BufferedImage(GAME_WIDTH, GAME_HEIGHT, BufferedImage.TYPE_INT_RGB);
	
	public void render() {
		BufferStrategy bs = canvas.getBufferStrategy();
		
		if(bs == null) {
			canvas.createBufferStrategy(3);
			return;
		}
		
		
		Graphics g = bs.getDrawGraphics();
		
		for(int i = 0; i < x.length; i++) {
			
			if(x[i]+offsetX > GAME_WIDTH || y[i] > GAME_HEIGHT)
				continue;
			
			if(x[i]+offsetX + SIZE < 0 || y[i] + SIZE < 0)
				continue;
			
			image.getGraphics().drawImage(tile, x[i]+offsetX, y[i], null);
		}
		
		g.drawImage(image, 0, 0, GAME_WIDTH, GAME_HEIGHT, null);
		image.getGraphics().dispose();
		g.dispose();
		bs.show();
	}
	
	@Override
	public void run() {

		long lastTime = System.nanoTime();
		double nsPerTick = 1000000000/60D;

		int ticks = 0;
		int frames = 0;

		long lastTimer = System.currentTimeMillis();
		double delta = 0;

		while(true) {
			long now = System.nanoTime();
			delta += (now - lastTime)/nsPerTick;
			lastTime = now;

			while(delta >= 1) {
				ticks++;
				tick();
				delta -=1;
			}
			try {
				Thread.sleep(2);
			} 
			catch (InterruptedException e) {

				e.printStackTrace();
			}
			
			frames++;
			render();

			if (System.currentTimeMillis() - lastTimer >= 1000) {
				lastTimer += 1000;
				System.out.println(""+ticks+ " ticks, "+frames+ " frames");
				frames = 0;
				ticks = 0;
			}
		}
	}

}

Thanks in advance.

It seems to me that you are doing everything in your powers to stop the stuttering. It all comes down to the frame rate, and in Java2D you have less time to deal with processing spikes that happen naturally causing the game to stutter. There are a few solutions to it.

  1. Use something that is faster than Java2D.

If you want, OpenGL is a lot faster than Java2D, so it is able to handle those types of lag spikes better. You can use any of its multiple solutions in the form of LWJGL, JOGL, LibGDX (recommended), or Slick2D (deprecated but still good).

  1. If you insist on using Java2D, you might want to take a look at this…

Snow Example

There is really 2 ways of rendering, but stuttering is a natural phenomenon. The way that you deal with it is either making up for lost time using deltas, or you can set up your animations to render at certain frames in the process. Even big budget games suffer from this (especially when dealing with multi-player and server lag). If you need more speed, then I totally recommend moving up to OpenGL where these spikes rarely happen…

I guess I will have to start using LWJGL then.
I really don’t understand how it can randomly just stutter, while the framerate does not change at all.

You could also let us test it. It might be your computer, or you might even just be imagining stuff.

in short, its pretty common. the busier your game gets the less this effect is pronounced.

I have this problem even today with libgdx / opengl if you just render a tile map and scroll it.
This effect is stronger on more powerful machines.
so it obviously because of delta spikes but no smoothing ever can fix all of that

How are you rendering it, because you may be doing in ineffectively, are you batching?

I’ve been doing it for 10 years with different libraries and techniques. it doesnt matter.

there were huge threads on jgo way back on this topic too, just search.

has nothing to do with how you draw: just one sprites, ball from pong bouncing will show the stuttering.
actually that example will show it very strongly since there is nothing going on but the ball.
its a game loop delta problem.

even when I used HTML 5 I programmed a very simple pong game, same deal.

Look at this thread: Solving Stuttering With Fixed Timesteps, Once and For All

it was never really solved.

Bottom line: just make your game, as more shit goes on, this effect lessens.

I was about to think i was just paranoid because I was focusing so much on the stuttering thing that I might see it even more.

Thanks for the comments, I’ll just start with making the actual game instead of trying a billion different ways of rendering and processing to fix the stuttering.