3

Alright, i'm making a small game, and I need to limit my FPS, because, when I play on my really fast computer, I have around 850 FPS, and the game will go like, REALLY fast, and when I switch to my older computer, it goes alot slower, so I will need to limit my FPS to get this right. How do I limit my FPS? My main game loop:

    public void startGame(){
    initialize();
    while(true){
        drawScreen();
        drawBuffer();
        plyMove();

        //FPS counter
        now=System.currentTimeMillis(); 
        framesCount++; 
        if(now-framesTimer>1000){
            framesTimer=now; 
            framesCountAvg=framesCount; 
            framesCount=0; 
        }

        try{
            Thread.sleep(14);
        }catch(Exception ex){}
    }
}

How I draw the screen, and draw all of the other things, players, the ball, etc. The game is a pong remake, btw.

    public void drawBuffer(){
    Graphics2D g = buffer.createGraphics();
    g.setColor(Color.BLACK);
    g.fillRect(0,0,600,500);
    g.setColor(Color.GREEN);
    g.fillRect(ply1.getX(),ply1.getY(),ply1.getWidth(),ply1.getHeight());
    g.setColor(Color.RED);
    g.fillRect(ply2.getX(),ply2.getY(),ply2.getWidth(),ply2.getHeight());
    g.setColor(Color.WHITE);
    g.fillOval(ball1.getX(),ball1.getY(),ball1.getWidth(),ball1.getHeight());
    g.drawString("" + framesCountAvg,10,10);
}

public void drawScreen(){
    Graphics2D g = (Graphics2D)this.getGraphics();
    g.drawImage(buffer,0,0,this);
    Toolkit.getDefaultToolkit().sync();
    g.dispose();
}
Stan
  • 3,659
  • 14
  • 35
  • 42
  • 10
    Well, if your game's speed depends on number of FPSes, then the whole design is quite... bad. – Dr McKay Jun 02 '11 at 17:02
  • 2
    Instead of limiting FPS you can also make your game code actually respecting time elapsed (e.g. move less if your FPS is high and more if FPS is low). This you can get by taking difference of `System.nanoTime()` from the actual frame to the previous frame. – Howard Jun 02 '11 at 17:03
  • Is this a duplicate of http://stackoverflow.com/questions/3102888/game-development-how-to-limit-fps ? – Michael McGowan Jun 02 '11 at 17:07
  • I looked at that, but that didn't quite fix my problem, and I have no idea how to make it work – Stan Jun 02 '11 at 17:10

6 Answers6

4

It sounds like your display it tied to your game engine. Make sure the two are disconnected. You want the game playing at the same speed no matter what the framerate is. If your fast computer repaints the screen faster that is ok if the engine is causing the game to play at a constant speed.

jzd
  • 23,473
  • 9
  • 54
  • 76
  • I'm kind of puzzled on how to do this. I created a main game loop, I will put it into the OP. – Stan Jun 02 '11 at 17:08
  • @Stan, your main game loop would make movement/changes based on time rather than a cycle. – jzd Jun 02 '11 at 17:19
  • How will I make it based on a cycle? If I remove the Thread.sleep, it will go to about 850FPS, and I don't want that. – Stan Jun 02 '11 at 17:21
  • It is based on a cycle. Instead make your changes based on time. So that your game engine is calculating things faster/slower than your painting. – jzd Jun 02 '11 at 17:25
  • Even moreso, you probably want rendering happening in a different thread than game processing. The game processing produces content for rendering, and then the rendering engine can choose how much or little of the data to render. – Stefan Kendall Jun 02 '11 at 22:11
  • How to implement what jzd describes: http://gafferongames.com/game-physics/fix-your-timestep/ – Prof. Falken Oct 24 '12 at 07:02
2

Rather than limiting your FPS, make it so that the game doesn't go really fast when the fps is high.

Presumably you have code that does certain things each frame e.g. moves the character forward if a button is pressed. What you want to do instead is move the character forward an amount dependent on the amount of time that has passed since the previous frame.

τεκ
  • 2,994
  • 1
  • 16
  • 14
1

As aforementioned you need to separate your display loop from your update loop somewhere at the core of you game there is probably something like this

while (1)
{
    drawscene();
    update();
}

and in update you are advancing the time by a fixed amount e.g 0.17 sec. If you drawing at exactly 60fps then the animations are running in realtime, at 850fps everything would be sped by a factor 14 (0.17*850) to prevent this you should make your update time dependent. e.g.

elapsed = 0;
while (1)
{
   start = time();
   update(elapsed); 
   drawscene();
   sleep(sleeptime);
   end = time();

   elapsed = end - start;
}
Harald Scheirich
  • 9,676
  • 29
  • 53
0

A description of what I meant in my comment. Inside your method plyMove(); I suspect there is something like

plyMove() {
    ply1.x += amountX;
    ply1.y += amountY;
}

Instead make the movement depending on the time elapsed

plyMove(double timeElapsed) {
    ply1.x += amountX * timeElapsed;
    ply1.y += amountY * timeElapsed;
}

where you calculate timeElapsed from the time difference inside your main loop and scale it accordingly to get a decent movement.

double timePrev = System.currentTimeMillis();
while(true) {
    double timeNow = System.currentTimeMillis();
    double elapsed = timeNow - timePrev;

    drawScreen();
    drawBuffer();
    plyMove(0.001 * elapsed);

    timePrev = timeNow;
}
Howard
  • 38,639
  • 9
  • 64
  • 83
0

If you really want a fixed timeframe game you could do this:

float timer = 0;
float prevTime= System.currentTimeMillis();
while(true)
{
    draw();

    float currentTime = System.currentTimeMillis();
    timer += currentTime - prevTime;

    while (timer > UPDATE_TIME) // To make sure that it still works properly when drawing takes too long
    {
        timer -= UPDATE_TIME;
        update();
    }
}

Where UPDATE_TIME is at what interval you want to update at in milliseconds.

CptRed
  • 11
  • 1
-3

One way would be using

try {
    Thread.sleep(20);
} catch(InterruptedException e) {}

at the end of the main loop. Adjust the number to your needs.

Lanbo
  • 15,118
  • 16
  • 70
  • 147
  • 3
    This will slow the game down on both machines. That is not what the OP wants. – jzd Jun 02 '11 at 17:04
  • 1
    Well, this fixed the game going fast, it's on 60 FPS, but won't it run slower on my other slower computer then? – Stan Jun 02 '11 at 17:05