Для основного игрового цикла вы должны запустить цикл 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.Date,%20long%29 : « При выполнении с фиксированной скоростью каждое выполнение планируется относительно запланированного времени выполнения начального выполнения. Если выполнение задерживается по какой-либо причине (например, при сборке мусора или другой фоновой активности), два или более выполнения будут выполняться в быстрой последовательности «наверстать упущенное. В долгосрочной перспективе частота выполнения будет точно равна обратной величине указанного периода (при условии, что системные часы, лежащие в основе Object.wait (long), точны) ».
Поскольку вы обычно заранее не знаете, сколько времени занимает игровой цикл, установка таймера для выполнения игрового цикла каждые X миллисекунд (в зависимости от целевой частоты кадров) может привести к созданию нескольких сгруппированных кадров, которые будут выполняться всякий раз, когда кадр закончено вместо того, когда кадр запланирован. Когда это происходит ... зачем вообще использовать таймер?
Не поймите меня неправильно, таймер не плохой класс, но обычно он лучше подходит для небольших задач, которые необходимо выполнять периодически или в определенное время, например, почтовый клиент может захотеть проверять наличие новой почты каждые 5 минут, или счетчик может уменьшаться каждую секунду, чтобы отобразить обратный отсчет до начала гонки.
Я бы не ставил основной цикл в таймер. Скорее, я бы сделал цикл while, который обрабатывает каждый кадр, а затем использовал бы какую-то функцию хронометража (звучит так, как в Java, которая будет System.nanoTime), чтобы вычислить, сколько времени прошло с момента последнего кадра / последней итерации петля.
Определенные языки здесь являются исключениями (например, JavaScript, ActionScript), потому что эти языки работают в среде, в которой есть неявный основной цикл (например, браузер, Flash Player), но это исключение не относится к Java.
источник