Question

Trying to figure out where to go from here. My update code is contained in my GameThread class, while my paint code is contained in my GamePanel class (which extends JPanel).

I want to be able to calculate the average frame rate/FPS in this but I'm not sure where to go from here. I currently calculate the elapsed time in my Update() loop but I also need to take into consideration my paintComponent() method in my GamePanel class.

Where would I go from here? What's the best way to calculate FPS based on this setup?

    package networkresearch;

    import java.awt.Graphics;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;

    /**
     *

     */
    public class GamePanel extends CorePanel {
        NetworkResearch ui;
        GameThread gameThread;
        ServerThread serverThread;

        BufferedImage[] images_players;

        ArrayList<Player> players;

        BufferedImage gameBackground;   

        long startTime = 0;
        long endTime = 0;

        GamePanel(NetworkResearch ui) throws IOException{
            images_players = new BufferedImage[5];
            images_players[0] = ui.loadAsset("player_knight.png");
            images_players[1] = ui.loadAsset("player_goblin.png");
            images_players[2] = ui.loadAsset("player_ogre.png");
            images_players[3] = ui.loadAsset("player_skeleton.png");
            images_players[4] = ui.loadAsset("player_wolf.png");
            this.ui = ui;
            JTextField nameField = new JTextField("Test Player");
            nameField.setColumns(6);
            add(nameField);

            gameBackground = ui.loadAsset("gameBackground.png");
            players = new ArrayList();
            Player player = new Player(images_players[4]);
            players.add(player);

            gameThread = new GameThread(this);
            serverThread = new ServerThread();
        }
        @Override
        public void keyTyped(KeyEvent e){
        }
        @Override
        public void keyPressed(KeyEvent e){
            for(Player player : players){
                switch(e.getKeyChar()){
                    case 'a':
                        player.keyLeft = true;
                        break;
                    case 's':
                        player.keyDown = true;
                        break;
                    case 'd':
                        player.keyRight = true;
                        break;
                    case 'w':
                        player.keyUp = true;
                        break;
                }
            }
        }
        @Override
        public void keyReleased(KeyEvent e){
            for(Player player : players){
                switch(e.getKeyChar()){
                    case 'a':
                        player.keyLeft = false;
                        break;
                    case 's':
                        player.keyDown = false;
                        break;
                    case 'd':
                        player.keyRight = false;
                        break;
                    case 'w':
                        player.keyUp = false;
                        break;
                }
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(gameBackground, 0, 0, this);
            for(Player player : players){
                player.paint(g);
            }
            repaint();
        }
        @Override
        public void start() {
            this.setFocusable(true);
            gameThread.start();
            serverThread.start();
            startTime = new Date().getTime();
        }

        @Override
        public void stop(){
            gameThread.stop();
            serverThread.stop();
        }

    }

    class GameThread extends Thread{
        GamePanel game;
        GameThread(GamePanel game){
            this.game = game;
        }
        @Override
        public void run() {
            while(this.isAlive()){            
                for(Player player : game.players){
                    player.update();
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException ex) {
                    Logger.getLogger(GameThread.class.getName()).log(Level.SEVERE, null, ex);
                }
                game.endTime = new Date().getTime();
                long difference = game.endTime - game.startTime;
                System.out.println("Elapsed milliseconds: " + difference);
            }
        }   
    }


    class ServerThread extends Thread{

        @Override
        public void run() {
            while(this.isAlive()){

            }
        }   
    }
Was it helpful?

Solution

Declare these variables with your other declarations:

    long framerate = 1000 / 60;
    // time the frame began. Edit the second value (60) to change the prefered FPS (i.e. change to 50 for 50 fps)
    long frameStart;
    // number of frames counted this second
    long frameCount = 0;
    // time elapsed during one frame
    long elapsedTime;
    // accumulates elapsed time over multiple frames
    long totalElapsedTime = 0;
    // the actual calculated framerate reported

Now, when the program is preparing for a 'loop-around' of the code, insert this:

            // calculate the time it took to render the frame
            elapsedTime = System.currentTimeMillis() - frameStart;
            // sync the framerate
            try {
                // make sure framerate milliseconds have passed this frame
                if (elapsedTime < framerate) {
                    Thread.sleep(framerate - elapsedTime);
                }
                else {
                    // don't starve the garbage collector
                    Thread.sleep(5);
                }
            }
            catch (InterruptedException e) {
                break;
            }
            ++frameCount;
            totalElapsedTime += (System.currentTimeMillis() - frameStart);
            if (totalElapsedTime > 1000) {
                reportedFramerate = (long) ((double) frameCount
                        / (double) totalElapsedTime * 1000.0);
                // show the framerate in the applet status window
                System.out.println("fps: " + reportedFramerate);
                // repaint();
                frameCount = 0;
                totalElapsedTime = 0;
            }

Hopefully, the comment code is enough for you to get the gist of what is going on in this. Let me know if you have issues understanding this. Cheers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top