2014-03-12 55 views
0

试图找出从这里去哪里。 我的更新代码包含在我的GameThread类中,而我的paint代码包含在我的GamePanel类(它扩展了JPanel)中。使用线程在java中计算FPS?

我想能够计算平均帧速率/ 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()){ 

      } 
     } 
    } 

回答

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 

现在,当程序正在准备一个 '环围绕' 的代码,插入此:

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

希望评论代码足以让你了解这方面的内容。让我知道你是否有理解这个问题。干杯。

+0

非常感谢!尽管如此,仍然存在问题。 我需要得到我的paintComponent()方法的执行时间,因为目前我只能够获得运行更新循环所需的时间。我将如何实现这一目标? –

+0

类似于fps计数器,在方法中有三个变量,一个用于开始时间,一个用于结束时间,一个用于两者之间的差异。在'paintComponent'开始时,设置开始时间,并在方法结束时设置结束时间。找到两者和'return'之间的区别。你将不得不设置组件返回一长串。 –