Java 2D-программирование: различные подходы к созданию игрового цикла

Я новичок в программировании на Java, но чем больше я читаю, тем больше я смущен, потому что я видел несколько разных подходов к созданию игрового цикла: 1. Стандартный подход, который использует класс Timer (кажется, менее точным). 2. Более точный подход, который использует System.nanoTime. 3. Простой подход, который использует scheduleAtFixedRate.

Какой из них должен быть предпочтительным и где преимущества /недостатки каждого подхода? Заранее благодарим за любую информацию.

10 голосов | спросил user1812379 14 PMpSun, 14 Apr 2013 14:49:22 +040049Sunday 2013, 14:49:22

2 ответа


7

Для базового игрового цикла вы запустите цикл while, в течение которого вы получите время с помощью nanoTime (), определите, сколько времени прошло с момента последнего кадра, а затем обновите свой игровой процесс и сделайте рендеринг.

Использование http: //docs. oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime%28%29 , вы можете опросить прошедшее время. В основном ...

public static void main(String [ ] args)
{
    long current_frame_time = system.nanoTime();
    long last_frame_time = current_frame_time;

    while(gameIsRunning)
    {
        last_frame_time = current_frame_time;
        current_frame_time = system.nanoTime();

        long timeTaken = current_frame_time - last_frame_time;

        //update and render game here
    }
}

Этот базовый способ можно улучшить, например, http://www.koonsolo.com/news/dewitters-gameloop/ и http://gafferongames.com/game-physics/fix-your-timestep/

В качестве альтернативы вы можете создать таймер и установить этот таймер для запуска вашего обновления и рендеринга каждые X миллисекунд. Но есть некоторые недостатки в построении такого рода игр.

Согласно http://docs.oracle.com/javase /1.5.0/docs/api/java/util/Timer.html : " Соответствие каждому объекту Timer является одним фоновым потоком, который используется для выполнения всех задач таймера последовательно. Задачи таймера должен выполняться быстро. Если задание таймера занимает слишком много времени для завершения, оно «запускает» поток выполнения задачи таймера. В свою очередь, это может задержать выполнение последующих задач, которые могут «сгруппироваться» и выполняться с быстрой последовательностью, когда ( и если) окончательная завершающая задача завершается. "

Согласно http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html#scheduleAtFixedRate%28java.util.TimerTask,%20java.util. Дата,% 20long% 29 : « При выполнении с фиксированной ставкой каждое исполнение запланировано относительно запланированного времени выполнения первоначального выполнения. Если исполнение задерживается по любой причине (например, сбор мусора или другая фоновая активность), произойдет два или более исполнения в быстрой последовательности, чтобы «догнать». В конечном счете частота выполнения будет в точности обратной за указанный период (если системные часы, лежащие в основе Object.wait (long), точны). "

Поскольку вы, как правило, не знаете заранее, сколько времени занимает игровой цикл, установка таймера для выполнения вашего gameloop каждые X миллисекунд (в зависимости от целевой частоты кадров) может привести к нескольким сложенным кадрам, которые будут выполняться всякий раз кадр закончен, а не когда запланирован кадр. Когда это произойдет ... зачем использовать таймер в первую очередь?

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

ответил Exilyth 14 PMpSun, 14 Apr 2013 16:40:54 +040040Sunday 2013, 16:40:54
7

Я бы не поставил основной цикл в таймер. Скорее я бы сделал цикл while, который обрабатывает каждый кадр, а затем использует какую-то функциональность хронометража (это похоже на Java, которая была бы System.nanoTime), чтобы вычислить, сколько времени прошло с момента последнего кадра /последней итерации цикл.

Определенные языки здесь являются исключениями (например, JavaScript, ActionScript), поскольку эти языки работают в среде, в которой есть неявный основной цикл для подключения (например, браузер, Flash Player), но это исключение не распространяется на Java .

ответил jhocking 14 PMpSun, 14 Apr 2013 18:05:18 +040005Sunday 2013, 18:05:18

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132