Search code examples
javaframesgame-loop

Java creating game loop (game update)


In my 2D game, I am not sure about my FPS and my game frame update method. When I want it to print out, to check if it is working in the console, it never writes anything. Am I missing something?

public class Main extends JFrame implements Runnable{

private static final long serialVersionUID = 1L;

static boolean running = true;

/* My game fps */
public void run() {

    int FRAMES_PER_SECOND = 25;
    int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;
    long next_game_tick = System.currentTimeMillis();
    long sleep_time = 0;

    while(running){

        updateGame();
        System.out.println("game updated")
        next_game_tick = SKIP_TICKS;
        sleep_time = next_game_tick - System.currentTimeMillis();

        if(sleep_time > 0){

            try {

                Thread.sleep(sleep_time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public static void main(String[] args){

    platform g = new platform();
    g.setVisible(true);
    g.setSize(900, 900);
    g.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    g.setResizable(false);

    (new Thread(new Main())).start();
}   

private void updateGame() {

    /*(e.g)all game code*/
}

}

and is my thread running correctly?


Solution

  • You can use the method ScheduledExecutorService.scheduleAtFixedRate():

    public class GameLoop {
        private static final int FPS = 60;
    
        public static void main(String[] args) {
            new GameLoop().startGame();
        }
    
        private void startGame() {
            ScheduledExecutorService executor = Executors
                    .newSingleThreadScheduledExecutor();
            executor.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    updateGame();
                }
            }, 0, 1000 / FPS, TimeUnit.MILLISECONDS);
        }
    
        private void updateGame() {
            System.out.println("game updated");
            // the game code
        }
    }
    

    This calls the method updateGame 60 times per second. Unlike the method ScheduledExecutorService.scheduleAtFixedDelay(), this method tries to keep up. So if one game tick took long enough to delay the next game tick, the executor service will consider this in the calculation for the next sleep duration.