2009-04-20 5 views
0

J'essaie de garder mon jeu à 60fps, mais je reçois des résultats étranges de mon code comme "2-8000 fps" Pourquoi est-ce pas rester à 60?obtenir des résultats étranges de framerate code

public static void main(String[] args) { 

     joglplat m = new joglplat(); 
     while(true){ 
      long startTime = System.nanoTime()/1000000; 
       try 
      { 
       //     123456: 6 zeros => 16ms 
       long nsToSleep = 16000000 - (System.nanoTime() - lastFrame); 
       System.out.println("ns: " + nsToSleep); 
       lastFrame = System.nanoTime(); 

       if(nsToSleep > 0) 
       { 
        System.out.println("ns2: " + (nsToSleep/1000)); 
        System.out.println("ns3: " + (nsToSleep%1000)); 
        Thread.sleep(nsToSleep/16000000, (int)(nsToSleep % 1000)); 
       } 
       else 
       { 
        Thread.yield(); // Only necessary if you want to guarantee that 
            // the thread yields the CPU between every frame 
       } 

      } 

      catch(Exception e){ 
       e.printStackTrace(); 
      } 

      m.controls(); 
      m.update(); 
      m.repaint(); 
      System.out.println("framerate: " + (System.nanoTime()/1000000 - startTime)); 
     } 
    } 

Répondre

1

Votre sortie est le nombre de secondes pendant lequel votre programme a fonctionné, pas le framerate. Vous devez diviser votre nombre de trames (que vous ne collectez pas) par la durée totale.

Pour obtenir le nombre d'images, il suffit d'ajouter une nouvelle à l'extérieur variable de la boucle de jeu, et incrémenter chaque fois par ...

public static void main(String[] args) { 
    long frames = 0; 
    joglplat m = new joglplat(); 
    while(true){ 
     frames++; 
     // other code here 
     System.out.println("framerate: " + ((System.nanoTime()/1000000 - startTime)/frames)); 
    } 
} 

Notez, cependant, que cela vous donnera le framerate moyen tout au long l'exécution complète de votre programme. Vous avez deux autres options: obtenir le framerate instantané et le framerate moyen sur les N frames précédents.

Tous les styles dans un (non testé/décompilé, donc peut-être des erreurs, mais devrait vous aider à démarrer dans la bonne direction):

public static void main(String[] args) { 
    long startTime = System.nanoTime(); 
    long lastFrameTime = startTime; 
    long frames = 0; 
    int framesToAverage = 10; 
    long[] frameTimes = new long[framesToAverage]; 
    joglplat m = new joglplat(); 
    while(true){ 
     // logic here 
     long currentFrameDuration = System.nanoTime() - lastFrame; 
     lastFrameTime = System.nanoTime(); 
     long instantFramerate = currentFrameDuration/1000000; 
     int currentFrameIndex = frames % frameTimes.length; 
     frameTimes[currentFrameIndex] = currentFrameDuration; 
     frames++; 
     long averageFramerate = ((lastFrameTime - startTime)/frames)/1000000; 
     long instantFramerate = currentFrameDuration/1000000; 
     if(frames > frameTimes.length) { // if it isn't, we don't have enough data yet 
      int firstFrameIndex = currentFrameIndex + 1; 
      if(firstFrameIndex > frameTimes.length) { 
       firstFrameIndex = 0; 
      } 
      long averageFrameratePerN = ((frameTimes[currentFrameIndex] - frameTimes[firstFrameindex])/frameTimes.length)/1000000; 
     } 

     // yield/sleep here 
    } 
} 
+0

Où puis-je collectionne le cadre compte? et comment? – William

+0

J'ai mis à jour la réponse avec un peu plus d'informations – Illandril

1

Je soupçonne que cela est causé par l'inexactitude des Thread.sleep():

provoque le thread en cours d'exécution dormir (cesser l'exécution) pour le nombre de millisecondes, plus le nombre spécifié de nanosecondes, sous réserve de la précision et de la précision des temporisateurs et des planificateurs du système. Le thread ne perd la propriété d'aucun moniteur .

Y a-t-il une raison pour laquelle vous devez maintenir le taux de framerate comme ça? Peut-être pouvez-vous expliquer plus en détail ce que vous essayez d'accomplir?

Questions connexes