Почему мой FPS / TPS не меняется, когда приложение на самом деле отстает? - PullRequest
0 голосов
/ 17 октября 2019

Привет, поэтому я использую алгоритм с фиксированным временным шагом, полученный от этого сайта , и по некоторым причинам мои FPS и TPS почти всегда равны 60, возможно, иногда снижаются до 55 или иногда до 61. ЯМне удалось использовать макрос для рассылки спама моему приложению и заметно запаздывающего времени до 5-10 кадров в секунду и ужасного времени ответа, но мои счетчики FPS и TPS по-прежнему отображают около 55 - 60 ... куда я иду?

Дополнительная информация: алгоритм вызывается с помощью метода Runnable run в новом потоке.


// Game Loop constants & variables
private static final int ONE_SECOND = 1000000000; // in nanoseconds
private static final double TARGET_TPS = 60;
private static final double TARGET_FPS = 60;
private static final double TIME_PER_TICK = ONE_SECOND / TARGET_TPS;
private static final double TIME_PER_FRAME = ONE_SECOND / TARGET_FPS;
int fps = (int)TARGET_TPS;
int tps = (int)TARGET_FPS;

private void gameloopFixedTimestep() {
    //At the very most we will update the game this many times before a new render.
    //If you're worried about visual hitches more than perfect timing, set this to 1.
    final int MAX_UPDATES_BEFORE_RENDER = 1;

    //We will need the last update time.
    double lastUpdateTime = System.nanoTime();
    //Store the last time we rendered.
    double lastRenderTime = System.nanoTime();

    // for FPS
    long nowTime;
    long lastTime = System.nanoTime();
    long lastFpsTime = 0;
    int frameCount = 0;
    int tickCount = 0;


    // keep looping round till the game ends using Exclusive-Or (^)
    while (this.isRunning)
    {
        nowTime = System.nanoTime();
        long updateLengthTime = nowTime - lastTime;
        lastTime = nowTime;
        //double deltaTicks = updateLengthTime / TIME_PER_TICK;
        int updateCount = 0;

        //Do as many game updates as we need to, potentially playing catchup.
        while( nowTime - lastUpdateTime > TIME_PER_TICK && updateCount < MAX_UPDATES_BEFORE_RENDER )
        {
            update();
            lastUpdateTime += TIME_PER_TICK;
            updateCount++;
            tickCount++;
        }

        //If for some reason an update takes forever, we don't want to do an insane number of catchups.
        //If you were doing some sort of game that needed to keep EXACT time, you would get rid of this.
        if ( nowTime - lastUpdateTime > TIME_PER_TICK)
        {
            lastUpdateTime = nowTime - TIME_PER_TICK;
        }

        //Render. To do so, we need to calculate interpolation for a smooth render.
        //float interpolation = Math.min(1.0f, (float) ((now - lastUpdateTime) / TIME_PER_TICK) );
        //render();
        repaint();
        frameCount++;

        lastRenderTime = nowTime;

        //Update the frames we got.
        lastFpsTime += updateLengthTime;
        if (lastFpsTime >= ONE_SECOND) {
            this.fps = frameCount;
            this.tps = tickCount;
            lastFpsTime = 0;
            frameCount = 0;
            tickCount = 0;
        }

        //Yield until it has been at least the target time between renders. This saves the CPU from hogging.
        while ( nowTime - lastRenderTime < TIME_PER_FRAME && nowTime - lastUpdateTime < TIME_PER_TICK)
        {
            Thread.yield();

            //This stops the app from consuming all your CPU. It makes this slightly less accurate, but is worth it.
            //You can remove this line and it will still work (better), your CPU just climbs on certain OSes.
            //FYI on some OS's this can cause pretty bad stuttering.
            try {Thread.sleep(1);} catch(Exception e) {} 

            nowTime = System.nanoTime();
        }
    }
}
...