문제

나는 게임을 60fps로 유지하려고 노력하고 있지만 "2-8000 fps"와 같은 코드에서 이상한 결과를 얻고 있습니다. 왜 이것이 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 ) );
    }
}

그러나 이것은 프로그램의 전체 실행에 걸쳐 평균 프레임 속도를 줄 것입니다. 다른 두 가지 옵션은 즉각적인 프레임 속도를 얻는 것입니다.

하나의 모든 스타일 (테스트되지 않은/고통받지 않으므로 오류가있을 수 있지만 올바른 방향으로 시작해야 함) :

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