2017-10-16 6 views
0

J'ai un jeu Pong avec un compteur FPS mais j'ai quelques problèmes. Je veux que le compteur FPS ne soit pas limité à 60 FPS, je veux que le compteur FPS soit aussi haut que possible.Le jeu Pong fonctionne trop vite avec le compteur FPS

Le FPS fonctionne actuellement, mais le problème est que le jeu tourne vraiment vite, je veux que le jeu tourne toujours à une vitesse jouable. J'ai essayé d'ajouter une minuterie pendant 5 ms mais cela a causé le mauvais fonctionnement du compteur FPS.

Je veux que le compteur FPS ne soit pas limité à 60 FPS mais utilise en même temps une sorte de minuterie. Voici mon code:

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

Cela semble être une question sémantique; Si le jeu ne redessine rien de plus rapide que 60fps, pourquoi le compteur devrait-il afficher quelque chose de plus élevé? –

+0

Ne pas appeler update de paintComponent. Je ne suis pas sûr de ce que vous essayez de faire dans cette méthode. Il devrait avoir des instructions sur la façon de peindre le panneau, rien d'autre. – Steven

+1

Je suis confus, pourquoi voudriez-vous que le fps soit différent du taux réel le cadre est mis à jour? Dans tous les cas, vous voulez mettre à jour l'état du jeu séparément de la repeinte, sinon ils sont liés au même intervalle ou faire le mouvement basé sur le temps écoulé plutôt que fixe. Je ne verrais pas beaucoup d'avantages à repeindre aussi vite que possible, ce n'est pas nécessaire. –

Répondre

1

Votre jeu fonctionne très rapidement, car vous utilisez un incrément statique dans chaque cycle de processeur. Si vous exécutez ce programme sur un cpu lent, votre jeu sera plus lent. Si vous le lancez avec un processeur rapide, votre jeu fonctionnera plus vite.

cpu 1: 100 cycles par seconde: votre balle se déplace de 300 unités par seconde.

cpu 2: 2000 cycles par seconde: votre balle se déplace 6000 unités par seconde. Lorsque vous avez plafonné votre jeu à 60 fps, vous évitez ce problème, car la mise à jour ne se fera que 60 fois par seconde et non 100 ou 2000 fois.

Une autre option consiste à impliquer l'heure. Cela signifie que vous mesurez le temps écoulé depuis la dernière image et que vous l'utilisez comme un multiplicateur. Plus votre processeur est rapide, plus votre temps entre les images sera court. Votre balle bougera selon votre temps. Si votre processeur est plus lent, le temps entre vos images augmente et la balle se déplace plus loin.

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

Alternativement, un grand article pour les boucles jeu: https://gafferongames.com/post/fix_your_timestep/