Привет, поэтому я использую алгоритм с фиксированным временным шагом, полученный от этого сайта , и по некоторым причинам мои 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();
}
}
}