2016-04-14 2 views
2

Я программирую игру на Java, и я ограничиваю FPS до 60. Я выяснил два разных способа получить тот же результат, но мне интересно, какой из них является лучшим/чистым способом сделать это. Или, может быть, у вас другая идея.while loop или Thread.sleep()?

while(System.nanoTime() - thisFrame < fps_limit); 

или

Thread.sleep(sleepingTime); 

Мое мышление является то, что в то время как петля эффекты ЦП более Thread.sleep, я прав?

Заранее благодарим за вашу помощь!

Дом

+0

'Thread.sleep' не спать точное количество времени. Он может спать немного дольше; и как только поток просыпается, он может не работать с тем же приоритетом, что и ранее. ([Далее] (http://stackoverflow.com/questions/23169557/thread-sleep-and-precise-timing)). –

+0

Если вы нацелены на точность ns, это не сработает, если вы нацеливаете время> 10 мс, вы будете прекрасно в порядке – Walfrat

ответ

2

У вас есть следующие основные параметры:

  1. Хотя цикл - Это будет потреблять циклы процессора и часто фактически остановить систему, потому что в то время как вы зацикливание, другие потоки не могут работать (на одной сердцевине машина).
  2. Thread.sleep() - Это может быть эффективным, но вы должны помнить, что не гарантируется, что он подождет указанное время.
  3. DelayQueue - Больше актуальности. Лучшее/точное время.
  4. ScheduledThreadPoolExecutor - Еще актуальней, чем DelayQueue. Использует Thread Pool.
+0

Что значит другие потоки can not run? они все еще в вашем программном счетчике? –

+0

Цикл while - оживленное ожидание, означающее, что он будет потреблять ресурсы процессора, ничего не делая ... ресурсы и время, которое могло быть использовано для выполнения другого потока ... – Madhusudhan

+0

@ user3493289 другие темы по-прежнему в вашем программном счетчике справа? –

0

Вы правы, в то время как с добиться того, что вы пытаетесь сделать, цикл while будет держать процессор занят, потребляя процессорное время.

В отличие от этого, Thread.sleep() освобождает процессор на указанное количество времени.

Итак, Thread.sleep() лучше.

0

Я согласен с @ayush - в то время как циклы обычно блокируют функции, тогда как потоки больше похожи на функции, управляемые прерываниями или параллельные функции программирования. Я немного зелёный на Java, но не мог ли вы настроить таймер, а не спать?

Да, похоже, что существуют таймерные конструкции, как на C++. Проверьте это: Timer in Java Thread

+0

по ссылке (http://www.java-gaming.org/index.php? topic = 24220.0) nhouser9 опубликовали, что говорят, что Таймер прост в настройке и более или менее точен, но TimerTask следует делать быстро. Этого достаточно для AmateurProjects, но недостаточно для меня;) –

0

Оба ответных сообщения уже хороши - сон лучше, чем цикл. Однако вы можете более подробно рассказать о том, как написать хороший цикл. Если вам интересно, вот большой ресурс: http://www.java-gaming.org/index.php?topic=24220.0

Он охватывает такие темы, как переменная timestep и интерполяция, которая может использоваться для того, чтобы ваша графика выполнялась очень плавно. Это решает проблемы, с которыми Thread.sleep не был на 100% точным в своем сроке, а также предотвращал появление вашей отрывистой графики, если ваша игра выполняет некоторые вычисления, требующие определенного времени.

0

Вы не должны использовать ни один из них.Пожалуйста, обратите внимание на документацию для ScheduledThreadPoolExecutor

В частности, вы смотрите на эту функцию

ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit) 
+0

Что делать, если ваш последний цикл не закончен до следующего запланированного времени? –

+0

Это означает, что вы недооценили свой период, и требуемые тяжелые вычисления обязательно изменили бы ваши fps, которые напрямую повлияли бы на период. – Madhusudhan

+0

Но как вы рассчитываете минимум? вы не всегда знаете аппаратное обеспечение пользователя, и если в его процессоре много разных задач. Не могли бы вы опубликовать некоторый псевдокод, любопытный, как будет выглядеть полный игровой цикл. –

0

Что бы я сделал (псевдокод).

//timepast since last loop in ms 
timepast = 0 
fpslimit = 60 
finished = true; 
//while the game is running 
while(runnning) 
{ 
    timepast += timeSinceLastrun 
    if(timepast > 1second/fpslimit && finished) 
    {    
      finished = false  
      dostuff(timepast) 
    } 
    //sleep for the time of 1second/fpslimit - timepassed to avoid cpu blocking 
    Thread.sleep((1second/fpslimit) - timepast) 
} 

dostuff(deltatime) 
{ 
    //do stuff in the end after it finished set 
    //finished to true so dostuff can be called again 
    finished = true 
    timepast=0 
} 

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

как OldCurmudgeon сказал thread.sleep dosnt заблокировать другие потоки в java и сделать процессор временем.

Thread.sleep заставляет текущий поток приостановить выполнение для заданного периода . Это является эффективным средством создания времени процессора доступны для других потоков приложения или других приложений , которые могут быть запущены на компьютере системы

Также вы можете передать timepast методу DoStuff как deltatime так игра работает одинаково на всех устройствах (одинаковая скорость).

-1

while loop будет использовать ресурс процессора, и это хорошо, только если ваше время ожидания не очень велико и ожидает точности.

Thread.sleep() хорошо, если нет точного не ожидается, как приоритет CPU изменится после того, как поток просыпается, и он может или не может быть запланировано немедленно бежать, и он также не должен использоваться как этот

while(! canContinue()) { 
    Thread.sleep(1000); 
} 

для приведенного выше случая, альтернативы эти случаи лучше использовать ожидания()/уведомляет(), если вы хотите, чтобы приостановить текущий поток и ждать другого потока, чтобы обработать то, а затем уведомить текущий поток продолжить ,

некоторые ссылки вы можете прочитать,

http://tutorials.jenkov.com/java-concurrency/thread-signaling.html

http://www.jsresources.org/faq_performance.html#thread_sleep