Java2D game loop stuttering

Hey. I am currently developing a 2D Java game using Swing components.
The game randomly stutters. Sometimes it runs completely smooth for the first minute and then it randomly jitters like mad, sometimes it starts of as a jittery mess.
Iv’e tried to omit certain parts of my code, thinking that they cause the lag, and now I am 100% sure that the problem lies within the way my game loop is written. Here it is:


package map;

public class GameLoop implements Runnable
{
	private Thread _gameThread;
	private MapPanel _gamePanel;
	private final double _updateCap = 1.0 / 60.0;
	private int _fps;
	
	public GameLoop(MapPanel panel)
	{
		this._gamePanel = panel;
	}
	
	public void startGame()
	{
		this._gameThread = new Thread(this);
		this._gameThread.start();
	}
	
	@Override
	public void run()
	{
		double firstTime = 0,
				lastTime = System.nanoTime() / 1000000000.0,
				passedTime = 0,
				unprocessedTime = 0,
				frameTime = 0;
		int frames = 0;
		
		while (this._gamePanel.isRunning())
		{
			firstTime = System.nanoTime() / 1000000000.0;
			passedTime = firstTime - lastTime;
			lastTime = firstTime;
			unprocessedTime += passedTime;
			frameTime += passedTime;
			
			while (unprocessedTime >= _updateCap)
			{
				unprocessedTime -= _updateCap;
				this.tick();
				
				if (frameTime >= 1.0)
				{
					frameTime = 0;
					_fps = frames;
					frames = 0;
					System.out.println("FPS: " + _fps);
				}
			}
			
			render();
			frames++;
			
			/**
			 * Preventing over-consumption of the CPU -
			 */
			try
			{
				Thread.sleep(1);
			}
			catch (InterruptedException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	private void render()
	{
		_gamePanel.repaint();
	}
	
	private void tick()
	{
		_gamePanel.setLogic();
	}
}


When am I doing wrong? What alternatives can you recommend if I want a game loop that can ensure a relatively smooth gameplay without dealing with anything that is way too advanced?
Thanks alot!

You’ll have better luck if you post a MCVE that demonstrates the problem.

One thing that sticks out to me is that it looks like you’re updating your game state on a different thread than the one that’s drawing your game.

[quote]What alternatives can you recommend if I want a game loop that can ensure a relatively smooth gameplay without dealing with anything that is way too advanced?
[/quote]
Use a library. I really like Processing.

The way the code is written we could have either of the following two scenarios (depending upon the values of unprocessedTime and _updateCap):

  • multiple tick() calls without intervening render() calls
  • multiple render() calls without intervening tick() calls

Could this cause the stuttering? Seems like that would be the likely result if the two need to alternate in order to preserve continuity.

I’d try moving timing stuff to after the update and render. They should just be run directly in sequence unless there is a good reason not to.

      while (this._gamePanel.isRunning())
      {
           tick();
           render();

           timeDiff = Systerm.currentTimeMillis() - beforeTime;
           sleepTime = PERIOD - timeDiff;   // I would imagine  PERIOD = 16 for just slightly better than 60fps?
           sleepTime = Math.max(sleepTime, 1); // even if lagging, sleep a little
           Thread.sleep(sleepTime);  // will need to be in try/catch or add exception handling
           beforeTime = system.currentTimeMillis(); 
      }

This code is slightly modified from “Killer Game Programming”.

I happen to think using a util.Timer or an ExecutorService (even better is the AnimationTimer provided in JavaFX) is the best way to go in terms of setting a steady FPS for a “game loop” rather than manually handling sleep times. But a lot of people will disagree, and there is no need to argue about it. Just do what works.

Using repaint often leaves games using Swing stuttering. The way I’ve fixed is to draw everything to a BufferedImage and then drawing that image to the screen.