Problem with FPS Counter

Hi,

In my main game loop, I am using this simple method to count the number of frames:

              long startTime = System.currentTimeMillis();
              fireShots();
              updatePosition();
              manageFighter();
              checkForGameEnd();
              manageEnemies();
              render();
              usedTime = System.currentTimeMillis() - startTime;

where the functions are pretty self-explaining for a 2d shooter game. They contain all the world logic and render() just calls the repaint() method from my graphical interface.

The problem is that I keep getting extremely low usedTime’s, +/- 1 msec. The problem is that it seems that a call to repaint() is pretty fast and that it doesn’t take into account the actual time to do the paint().

So would you suggest to set usedTime() at the end of the paint() or is there a better way ?

Update:

I tried to move the usedTime calculation at the end of the paint() function and am getting better results. My framerate is now around 40 fps which seems ok. But I keep getting an odd problem:
I am using a thread with a timeout of 40 to run the main game loop and as described in the Java2D forum, I am trying to blur the foreground BufferedImage on the fly to make it look better.
This gives me a very rough animation and the smoothness of the animation (which I get without using the BLUR) is gone.
But my framecounter keeps telling me that I have 50 FPS which is impossible when I look at the actual result ?!

System.currentTimeMillis() is a rather bad timer. It’s accuracy equals the Operating Sytem’s tick rate. 50-55msec on win9x, 10msec on 2k/xp/mac and 1msec (or so) on linux.

If you’re using 1.5 you can use System.nanoTime() instead - it’s a hi res timer.

KONI,

As far as I understand it, using repaint() is a really bad way to go for games. As you’ve probably realised by now, it simply schedules the targetted component for repainting the next time the Swing thread is free to do so, rather than actually repainting the GUI then and there.

The recommended way to do games is to turn off auto-repainting and force your own painting inside the render() method that you already have.

Chet’s gaming articles should help:

http://www.sys-con.com/story/?storyid=46663&DE=1

http://www.sys-con.com/story/?storyid=46983&DE=1

Add this method.


    public void paintFps(Graphics2D g) {
          g.setFont( new Font("Arial",Font.BOLD,12));
          g.setColor(Color.white);
          if (usedTime > 0){
              g.drawString(String.valueOf(1000000000/usedTime)+" fps",screenWidth-50,screenHeight-10);
          }else{
              g.drawString("--- fps",screenWidth-50,screenHeight-10);
          }
    }

Then do what oNyx suggested.
long startTime = System.nanoTime();

usedTime = System.nanoTime()-startTime;

usedTime is a private global.

Call paintFps in your render loop.

Then follow Grazer’s instructions, the componets should have all the setIgnoreRepaint(true);

And you should use a custom render loop.