Mi chiedevo se ci fosse qualche danno possibile quando il mio ciclo di gioco scorre veloce quanto il sistema lo consente?
Al momento ho un loop che, misurando il tempo trascorso in nanosecondi, esegue la logica di gioco e la logica di rendering a velocità predefinite senza problemi. In effetti, ogni logica che faccio nel loop è sincronizzata su una certa quantità di chiamate al secondo.
Il loop stesso, però, corre più veloce di quello che gli piace e arriva a circa 11,7 milioni di loop al secondo sulla mia macchina.
Loop (semplice pseudocodice):
while(!isGameOver){
if(canPollInputs){
pollInputs()
}
while(canStepLogic){
stepLogic()
}
if(canRender){
render()
}
}
La mia domanda è fondamentalmente se quel semplice loop, se non funziona a una velocità controllata, può danneggiare un sistema?
Modifica: ciò significa che la mia logica viene eseguita 30 volte al secondo (30 tps), il mio renderer funziona a 60 fps, eseguo il polling degli input 100 volte al secondo e c'è anche qualche logica per far fronte alla logica o al rendering impiegando più tempo del previsto . Ma il loop stesso non è limitato.
Modifica: usando Thread.sleep()
ad es. L'acceleratore del loop principale fino a 250 loop al secondo porta a una riduzione, ma i loop funzionano a circa 570 loop al secondo invece dei 250 desiderati (aggiungerà il codice quando sono sul mio computer desktop ..)
Modifica: Eccoci, un gameloop java funzionante per chiarire le cose. Inoltre, sentiti libero di usarlo ma non rivendicalo;)
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++;
}
}
Come puoi vedere non c'è quasi nessun codice eseguito su ogni loop ma sempre una certa selezione in base a quanto tempo reale è passato. La domanda si riferisce a quel "ciclo di lavoro" e al modo in cui influenza il sistema.