用线程计算java中的FPS?

时间:2014-03-12 05:11:47

标签: java frame-rate

试图找出从这里开始的地方。 我的更新代码包含在我的GameThread类中,而我的绘图代码包含在我的GamePanel类中(扩展了JPanel)。

我希望能够计算平均帧速率/ FPS,但我不知道从哪里开始。我目前在Update()循环中计算已用时间,但我还需要考虑我的GamePanel类中的paintComponent()方法。

我从哪里开始?基于此设置计算FPS的最佳方法是什么?

    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()){

            }
        }   
    }

1 个答案:

答案 0 :(得分:0)

使用其他声明声明这些变量:

    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

现在,当程序正在准备一个&#39;循环&#39;代码,插入:

            // 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;
            }

希望评论代码足以让您了解其中的内容。如果您对此有疑问,请告诉我。欢呼声。