Мне было интересно, есть ли какой-нибудь возможный вред, когда мой игровой цикл работает так быстро, как позволяет система?
В настоящее время у меня есть цикл, который, измеряя прошедшее время в наносекундах, без проблем запускает игровую логику и логику рендеринга на предопределенных скоростях. Фактически любая логика, которую я делаю в цикле, синхронизируется с определенным количеством вызовов каждую секунду.
Сам цикл, хотя и работает так быстро, как ему хочется, составляет около 11,7 миллионов циклов в секунду на моей машине.
Петля (простой псевдокод):
while(!isGameOver){
if(canPollInputs){
pollInputs()
}
while(canStepLogic){
stepLogic()
}
if(canRender){
render()
}
}
Мой вопрос заключается в том, может ли этот простой цикл, если он не работает на контролируемой скорости, причинить какой-либо вред системе?
Редактировать: это означает, что моя логика работает 30 раз в секунду (30 тактов в секунду), мой рендерер работает со скоростью 60 кадров в секунду, я опрашиваю ввод 100 раз в секунду, и есть также некоторая логика, чтобы справиться с логикой или рендерингом занимает больше времени, чем ожидалось , Но сама петля не задушена.
Редактирование: Использование, Thread.sleep()
например, для уменьшения основного цикла до 250 циклов в секунду, приводит к уменьшению, но циклы работают со скоростью около 570 циклов в секунду вместо желаемых 250 (добавит код, когда я на своем настольном компьютере ...)
Редактировать: здесь мы идем, рабочий Java Gameloop, чтобы прояснить вещи. Также не стесняйтесь использовать это, но не претендуйте на это свое;)
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++;
}
}
Как вы можете видеть, в каждом цикле практически не выполняется код, но всегда есть определенный выбор, основанный на том, сколько прошло реального времени. Вопрос касается этой «рабочей петли» и того, как она влияет на систему.