Ich habe mich gefragt, ob es einen möglichen Schaden gibt, wenn meine Spieleschleife so schnell läuft, wie es das System zulässt.
Ich habe derzeit eine Schleife, die durch Messen der verstrichenen Zeit in Nanosekunden die Spielelogik und die Renderlogik problemlos mit vordefinierten Geschwindigkeiten ausführt. Tatsächlich wird jede Logik, die ich in der Schleife tue, auf eine bestimmte Anzahl von Aufrufen pro Sekunde getaktet.
Die Schleife selbst läuft jedoch ungefähr so schnell wie sie möchte, was auf meiner Maschine ungefähr 11,7 Millionen Schleifen pro Sekunde ergibt.
Schleife (einfacher Pseudocode):
while(!isGameOver){
if(canPollInputs){
pollInputs()
}
while(canStepLogic){
stepLogic()
}
if(canRender){
render()
}
}
Meine Frage ist im Grunde, ob diese einfache Schleife, wenn sie nicht mit kontrollierter Geschwindigkeit läuft, einem System Schaden zufügen kann.
Bearbeiten: Das bedeutet, dass meine Logik 30-mal pro Sekunde (30 tps) ausgeführt wird, mein Renderer mit 60 fps ausgeführt wird, ich 100-mal pro Sekunde Eingaben abrufe und es gibt auch eine Logik, mit der Logik oder Rendern länger als erwartet fertig werden kann . Die Schleife selbst wird jedoch nicht gedrosselt.
Bearbeiten: Wenn Sie Thread.sleep()
z. B. die Hauptschleife auf 250 Schleifen pro Sekunde drosseln, führt dies zu einer Reduzierung, aber die Schleifen laufen mit etwa 570 Schleifen pro Sekunde anstelle der gewünschten 250 (Code wird hinzugefügt, wenn ich mich auf meinem Desktop-Computer befinde.)
Edit: Los geht's, ein funktionierender Java-Gameloop, um die Dinge zu klären. Fühlen Sie sich auch frei, es zu benutzen, aber fordern Sie es nicht von Ihnen an;)
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++;
}
}
Wie Sie sehen, wird fast kein Code in jeder Schleife ausgeführt, sondern immer eine bestimmte Auswahl, die davon abhängt, wie viel Echtzeit vergangen ist. Die Frage bezieht sich auf diese 'Worker-Schleife' und wie sie das System beeinflusst.