Странное поведение в Thread.sleep()

Я заметил кое-что очень странное (что в итоге приводит к сбою моей игры) с Thread.sleep() и я не могу понять, в чем может быть проблема. Я запускаю следующий метод в течение двух часов подряд, и результат всегда равен 100+-5;

public void gameLoop() {
    t0 = time();
    while (GameState.getInstance().getState() == GameCondition.RUNNING) {

        engine.update();
        sfx.play();

        t1 = time();
        delta = t1 - t0;

        gfx.render((int) delta);
        t0 = time();
        System.out.println(delta);
        sleep(100);
    }
}

Теперь, если я использую точно такой же метод, но вместо того, чтобы спать для постоянных 100, я сплю для delta

public void gameLoop() {
    t0 = time();
    while (GameState.getInstance().getState() == GameCondition.RUNNING) {

        engine.update();
        sfx.play();

        t1 = time();
        delta = t1 - t0;

        gfx.render((int) delta);
        t0 = time();
        System.out.println(delta);
        sleep(delta);
    }
}

И теперь вывод гласит:

0

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

2

....
 After a minute
 571

Я не знаю, если я слишком устал и совершил очевидную ошибку или что-то очень странное происходит, вот и сон.

private void sleep(long milliSeconds) {
    System.out.println();
    try {
        Thread.sleep(milliSeconds);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Редактировать: проблема? Дельта "протекает", поскольку внутренние методы (перед сном) практически не используют время (что доказано sleep(100) тест) Я ожидаю, что дельта будет очень точной с незначительными колебаниями, но она продолжает расти.

1 ответ

Решение

В вашем цикле вычисление дельты включает в себя время, ранее спавшее, а затем спит в течение этого нового времени дельты. Если сон (или ваш код) будет медленным (скажем, 1 мс, что может произойти), то в следующий раз ваша дельта будет на 1 мс больше, поэтому вы будете спать в течение 2 мс.

Ваша следующая итерация, так как вы спали в течение 2 мс в прошлый раз, будет не менее 2 мс. Если сон или ваш код снова медленно (что произойдет), то вы будете спать в течение 3 мс в следующий раз и так далее. Вы накапливаете всю медлительность, которая может возникнуть из-за вашей дельты, включая предыдущее время сна и любую ошибку в нем.

Другие вопросы по тегам