Je me demandais s'il y avait un danger possible lorsque ma boucle de jeu tourne aussi vite que le système le permet?
J'ai actuellement une boucle qui, en mesurant le temps passé en nanosecondes, exécute la logique du jeu et rend la logique à des vitesses prédéfinies sans problème. En fait, toute logique que je fais dans la boucle est cadencée à un certain nombre d'appels chaque seconde.
La boucle elle-même fonctionne à peu près aussi vite qu'elle le souhaite, ce qui représente environ 11,7 millions de boucles par seconde sur ma machine.
Boucle (pseudocode simple):
while(!isGameOver){
if(canPollInputs){
pollInputs()
}
while(canStepLogic){
stepLogic()
}
if(canRender){
render()
}
}
Ma question est essentiellement si cette simple boucle, si elle ne fonctionne pas à une vitesse contrôlée, peut nuire à un système?
Edit: cela signifie que ma logique fonctionne 30 fois par seconde (30 tps), mon moteur de rendu fonctionne à 60 ips, j'interroge les entrées 100 fois par seconde et il y a aussi une certaine logique pour faire face à la logique ou le rendu prend plus de temps que prévu . Mais la boucle elle-même n'est pas étranglée.
Edit: Utiliser Thread.sleep()
par exemple pour réduire la boucle principale à 250 boucles par seconde entraîne une réduction mais les boucles fonctionnent à environ 570 boucles par seconde au lieu des 250 souhaitées (ajoutera du code lorsque je serai sur ma machine de bureau ..)
Edit: C'est parti, une gameloop java fonctionnelle pour clarifier les choses. N'hésitez pas non plus à l'utiliser mais ne le revendiquez pas à vous;)
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++;
}
}
Comme vous pouvez le voir, il n'y a presque pas de code exécuté sur chaque boucle mais toujours une certaine sélection en fonction du temps réel écoulé. La question se réfère à cette «boucle des travailleurs» et comment elle influence le système.