2017-10-16 60 views
0

我有一個FPS計數器的乒乓遊戲,但我有一些問題。我希望FPS計數器不被限制在60 FPS,我希望FPS計數器儘可能高。Pong遊戲運行速度過快FPS計數器

FPS目前正在運行,但問題是遊戲運行速度非常快,我希望遊戲始終以可播放的速度運行。我試圖添加一個計時器5毫秒,但導致FPS計數器無法正常工作。

我希望FPS計數器不限制在60 FPS,但同時使用某種計時器。這裏是我的代碼:

package Game; 

import java.awt.*; 
import java.awt.event.*; 
import java.util.Random; 
import javax.swing.*; 

public class Main extends JPanel implements KeyListener, ActionListener{ 

// Lite variabler 
JFrame frame; 
int windowWidth, windowHeight; 
Point bollXY; 
int screenWidth, screenHeight; 
Image bildPaddel; 
Image bildBollen; 
int paddelY; 
int paddel2Y; 
boolean paddelUp, paddelDown; 
Random rand; 
int score, score2; 
boolean bollUp, bollRight, changeDirection; 
int fruktDistansRand; 
long time; 
int fps, newfps; 
int fpsTimesCounter; 

// Konstruktor 
public Main(){ 
    // Definera variabler 
    frame = new JFrame(); 
    bildPaddel = new ImageIcon("src/images/Player.png").getImage(); 
    bildBollen = new ImageIcon("src/images/Pong.png").getImage(); 
    bollXY = new Point(673, 352); 
    paddelY = 312; 
    paddel2Y = 312; 
    paddelUp = false; 
    rand = new Random(); 
    score = 0; 
    score2 = 0; 
    bollUp = false; 
    bollRight = false; 
    changeDirection = false; 
    fruktDistansRand = 0; 
    time = System.currentTimeMillis(); 
    fps = 0; 
    newfps = 0; 
    fpsTimesCounter = 0; 

    // Lyssnare 
    frame.addKeyListener(this); 

    // Bygga fönstret 

    frame.add(this); 

    // Obligatoriska egenskaper 
    frame.setTitle("Pong"); 
    frame.setSize(1366, 724); // Eftersom spelet inte ska vara helt i fullskärm sätts fönstret på 1366x724 så att aktivitetsfältet syns 
    frame.setVisible(true); 
    frame.setLocationRelativeTo(null); // Centrerar fönstret 
    frame.setResizable(false); 
    this.setBackground(Color.BLACK); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    bollUp = true; 
    bollRight = true; 
    changeDirection = false; 
    bollXY = new Point(); 

    frame.add(this); 
} 
// Metoder 
public static void main(String[] args) { 
    new Main(); 
} 

@Override 
public void paintComponent(Graphics g){ 
    super.paintComponent(g); 

    g.drawImage(bildBollen, bollXY.x, bollXY.y, null); 
    g.drawImage(bildPaddel, 50, paddelY, null); 
    g.drawImage(bildPaddel, 1300, paddel2Y, null); 
    g.setFont(new Font("Arial", Font.BOLD, 100)); 
    g.setColor(Color.WHITE); 
    g.drawString(score2 + "", 1002, 100); 
    g.drawString(score + "", 314, 100); 

    if(System.currentTimeMillis() - time >= 1000){ 
     time = System.currentTimeMillis(); 
     fps = newfps; 
     newfps = 0; 
    } 
    else{ 
     newfps++; 
    } 
    g.setFont(new Font("Arial", Font.BOLD, 25)); 
    g.drawString(fps + "", 5, 22); 

    update(); 
} 

public void AI(){ 

    fruktDistansRand = rand.nextInt(200) + 950; 
    if(bollXY.x > fruktDistansRand && bollXY.x < 1380 && bollRight && paddel2Y > 0 && paddel2Y < 596){ 
     if(paddel2Y + 50 < bollXY.y){ 
      paddel2Y = paddel2Y + 3; 
     } 
     else{ 
      paddel2Y = paddel2Y - 3; 
     } 
     if(paddel2Y <= 0){ 
      paddel2Y = paddel2Y + 3; 
     } 
     if(paddel2Y >= 596){ 
      paddel2Y = paddel2Y - 3; 
     } 
    } 
} 

public void ifUp(){ 
    if(bollUp){ 
     if(changeDirection){ 
      if(bollXY.y < 0){ 
       bollUp = false; 
      } 
      else{ 
       bollXY.y = bollXY.y - 3; 
      } 
     } 
     else{ 
      if(bollXY.y < 0){ 
       bollUp = false; 
      } 
      else{ 
       bollXY.y = bollXY.y - 3; 
      } 
     } 
    } 

    else{ 
     if(changeDirection){ 
      if(bollXY.y > 675){ 
       bollUp = true; 
      } 
      else{ 
       bollXY.y = bollXY.y + 3; 
      } 
     } 
     else{ 
      if(bollXY.y > 675){ 
       bollUp = true; 
      } 
      else{ 
       bollXY.y = bollXY.y + 3; 
      } 
     } 
    } 
} 

public void update(){ 
    if(paddelUp){ 
     if(paddelY > 0){ 
      paddelY = paddelY - 3; 
     } 
    } 
    if(paddelDown){ 
     if(paddelY < 596){ 
      paddelY = paddelY + 3; 
     } 
    } 

    if(bollRight){ 

     if(bollXY.x > 1290 && bollXY.x < 1300 && bollXY.y < paddel2Y + 100 && bollXY.y > paddel2Y-20){ 

      if(!bollUp && bollXY.y < paddel2Y){ 
       changeDirection = true; 
       bollUp = true; 
      } 
      else if(bollUp && bollXY.y > paddel2Y + 80){ 
       changeDirection = true; 
       bollUp = false; 
      } 

      bollRight = false; 
     } 
     else if(bollXY.x > 1600){ 
      score++; 
      bollXY.y = rand.nextInt(690); 
      bollXY.x = 678; 
     } 
     else 
      bollXY.x = bollXY.x + 3; 

     ifUp(); 
    } 
    else{ 
     if(bollXY.x > 50 && bollXY.x < 60 &&bollXY.y < paddelY + 100 && bollXY.y > paddelY-20){ 
      if(!bollUp && bollXY.y < paddelY){ 
       changeDirection = true; 
       bollUp = true; 
      } 
      else if(bollUp && bollXY.y > paddelY + 80){ 
       changeDirection = true; 
       bollUp = false; 
      } 
      bollRight = true; 
     } 
     else if(bollXY.x < -244){ 
      score2++; 
      bollXY.x = 678; 
      bollXY.y = rand.nextInt(596); 
     } 
     else 
      bollXY.x = bollXY.x - 3; 

     ifUp(); 
    } 
    AI(); 
    repaint(); 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    update(); 
} 

@Override 
public void keyPressed(KeyEvent e) { 
    if(e.getKeyCode() == KeyEvent.VK_W || e.getKeyCode() == KeyEvent.VK_UP){ 
     paddelUp = true; 
    } 
    if(e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_DOWN){ 
     paddelDown = true; 
    } 
} 

@Override 
public void keyReleased(KeyEvent e) { 
    if(e.getKeyCode() == KeyEvent.VK_W || e.getKeyCode() == KeyEvent.VK_UP){ 
     paddelUp = false; 
    } 
    if(e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_DOWN){ 
     paddelDown = false; 
    } 
} 

@Override 
public void keyTyped(KeyEvent e) { 

} 
} 
+1

這似乎是一個語義問題;如果遊戲沒有重繪速度超過60fps,爲什麼櫃檯顯示的東西更高? –

+0

不要從paintComponent調用更新。不知道你想用這種方法做什麼。它應該有如何繪製面板的指示,沒有別的。 – Steven

+1

我很困惑,爲什麼你想要fps與幀更新的實際速率不同?在任何情況下,您都想單獨更新遊戲狀態,否則它們將被綁定到相同的時間間隔,或者基於時間流逝而不是固定的進行移動。我認爲儘可能快地在重新繪製中看不到太多好處,但這不是必要的。 –

回答

1

由於您在每個cpu週期中使用了一個靜態增量,因此您的遊戲運行得非常快。如果你在慢速CPU上運行這個程序,你的遊戲運行速度會變慢。如果你用一個快速的CPU運行它,你的遊戲運行得更快。

cpu 1:每秒100個週期:你的球每秒移動300個單位。

cpu 2:每秒2000個週期:你的球每秒移動6000個單位。

當您以60 fps的速度上限您的遊戲時,您避免了該問題,因爲更新只會每秒發生60次,而不是100次或2000次。

另一種選擇是涉及時間。 這意味着您測量自上一幀以來的時間並將其用作乘數。你的CPU運行速度越快,幀間的時間就越短。你的球會根據你的時間移動。如果你的CPU速度較慢,幀間的時間增加,球會進一步移動。

float delta = // time between your frames 
pulic void update(float delta){ 
... 
bollXY.y -= delta * 3; 

或者遊戲一個偉大的文章循環:https://gafferongames.com/post/fix_your_timestep/