получение странных результатов из кода с частотой кадров

StackOverflow https://stackoverflow.com/questions/768857

  •  12-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь поддерживать скорость моей игры 60 кадров в секунду, но я получаю странные результаты из своего кода, например "2-8000 кадров в секунду", Почему это не остается на уровне 60?

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));
        }
    }
Это было полезно?

Решение

Ваш результат — это количество секунд, в течение которых работала ваша программа, а не частота кадров.Вам следует разделить количество кадров (которое вы не собираете) на общее время работы.

Чтобы получить количество кадров, просто добавьте новую переменную вне игрового цикла и увеличивайте ее каждый раз...

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

Однако учтите, что это даст вам среднюю частоту кадров на протяжении всего выполнения вашей программы.Два других варианта — получить мгновенную частоту кадров и среднюю частоту кадров за последние N кадров.

Все стили в одном (непроверенные/нескомпилированные, поэтому могут быть некоторые ошибки, но это поможет вам начать в правильном направлении):

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

Другие советы

Я подозреваю, что это вызвано неточностью Thread.sleep():

Переводит текущий выполняющийся поток в спящий режим (прекращает выполнение) на указанное количество миллисекунд плюс указанное количество наносекунд, при условии соблюдения точности системных таймеров и планировщиков. Поток не теряет права собственности ни на какие мониторы.

Есть ли какая-то причина, по которой вы должны вот так снижать частоту кадров?Возможно, вы могли бы более подробно объяснить, чего вы пытаетесь достичь?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top