Fiquei me perguntando se existe algum dano possível quando o loop do jogo é executado o mais rápido que o sistema permite?
Atualmente, tenho um loop que, medindo o tempo passado em nanossegundos, executa a lógica do jogo e processa a lógica em velocidades predefinidas sem problemas. De fato, qualquer lógica que eu faça no loop é cronometrada para uma certa quantidade de chamadas a cada segundo.
O loop em si, no entanto, roda tão rápido quanto ele gosta, chegando a cerca de 11,7 milhões de loops por segundo na minha máquina.
Loop (pseudocódigo simples):
while(!isGameOver){
if(canPollInputs){
pollInputs()
}
while(canStepLogic){
stepLogic()
}
if(canRender){
render()
}
}
Minha pergunta é basicamente se esse loop simples, se não estiver funcionando a uma velocidade controlada, pode causar algum dano a um sistema?
Edit: Isso significa que minha lógica está rodando 30 vezes por segundo (30 tps), meu renderizador está rodando a 60 fps, estou pesquisando entradas 100 vezes por segundo e também há alguma lógica para lidar com a lógica ou renderização levando mais tempo do que o esperado . Mas o loop em si não é regulado.
Editar: Usar Thread.sleep()
para, por exemplo, acelerar o loop principal até 250 loops por segundo leva a uma redução, mas os loops são executados em torno de 570 loops por segundo em vez dos 250 desejados (adicionará código quando estou na minha máquina de trabalho ..)
Edit: Aqui vamos nós, um gameloop java de trabalho, a fim de esclarecer as coisas. Também fique à vontade para usá-lo, mas não o reivindique;)
private void gameLoop() {
// Time that must elapse before a new run
double timePerPoll = 1000000000l / targetPPS;
double timePerTick = 1000000000l / targetTPS;
double timePerFrame = 1000000000l / targetFPS;
int maxFrameSkip = (int) ( (1000000000l / MINIMUM_FPS) / timePerTick);
int achievedPPS = 0;
int achievedFPS = 0;
int achievedTPS = 0;
long timer = TimeUtils.getMillis();
int loops = 0;
int achievedLoops = 0;
long currTime = 0l;
long loopTime = 0l;
long accumulatorPPS = 0l;
long accumulatorTPS = 0l;
long accumulatorFPS = 0l;
long lastTime = TimeUtils.getNano();
while(!isRequestedToStop) {
currTime = TimeUtils.getNano();
loopTime = currTime - lastTime;
lastTime = currTime;
loops = 0;
accumulatorPPS += loopTime;
accumulatorTPS += loopTime;
accumulatorFPS += loopTime;
if(accumulatorPPS >= timePerPoll) {
pollInputs();
playerLogic();
achievedPPS++;
accumulatorPPS -= timePerPoll;
}
while(accumulatorTPS >= timePerTick && loops < maxFrameSkip) {
tick();
achievedTPS++;
accumulatorTPS -= timePerTick;
loops++;
}
// Max 1 render per loop so player movement stays fluent
if(accumulatorFPS >= timePerFrame) {
render();
achievedFPS++;
accumulatorFPS -= timePerFrame;
}
if(TimeUtils.getDeltaMillis(timer) > 1000) {
timer += 1000;
logger.debug(achievedTPS + " TPS, " + achievedFPS + " FPS, "
+ achievedPPS + " Polls, " + achievedLoops + " Loops");
achievedTPS = 0;
achievedFPS = 0;
achievedLoops = 0;
}
achievedLoops++;
}
}
Como você pode ver, quase não há código executado em cada loop, mas sempre uma certa seleção com base em quanto tempo real se passou. A questão está se referindo a esse 'loop de trabalho' e como ele influencia o sistema.