Converting to Active Rendering
The current painting strategy is to call repaint() in run()'s animation loop:
while(running) {
gameUpdate(); // game state is updated
gameRender(); // render to a buffer
repaint(); // paint with the buffer
try {
Thread.sleep(20); // sleep a bit
}
catch(InterruptedException ex){}
}Since a call to repaint() is only a request, it's difficult to know when the repaint has been completed. This means that the sleep time in the animation loop is little more than a guess; if the specified delay is too long, then the animation speed is impaired for no reason. If the delay is too short, then repaint requests may be queued by the JVM and skipped if the load becomes too large.
In fact, no single sleep time is satisfactory since the time taken to update and render a frame will vary depending on the activity taking place in the game. The sleep time must be calculated afresh each time round the loop after measuring the iteration's update and rendering periods. Unfortunately, the repaint() part of the rendering is done by the JVM and cannot be easily measured.
As a first step to dealing with these issues, I switch to active rendering, shown below as modifications to run():
public void run()
/* Repeatedly update, render, sleep */
{
running = true;
while(running) {
gameUpdate(); // game state is updated
gameRender(); // render to a buffer
paintScreen(); // draw buffer to screen try { Thread.sleep(20); // sleep a bit } catch(InterruptedException ex){} } System.exit(0); ...