Я пишу довольно простую двухмерную многопользовательскую сетевую игру.Прямо сейчас я почти не могу создать стабильную петлю.Под стабильным я подразумеваю цикл такого рода, внутри которого выполняются определенные вычисления и который повторяется в течение строгих периодов времени (скажем, каждые 25 мс, вот за что я сейчас борюсь).До сих пор я не сталкивался со многими серьезными препятствиями, за исключением этого.
В этой игре запущено несколько потоков, как в серверных, так и в клиентских приложениях, назначенных для различных задач.Давайте возьмем, например, поток движка в моем серверном приложении.В этой теме я пытаюсь создать игровой цикл с использованием Thread.sleep, пытаясь учесть время, затрачиваемое игровыми вычислениями.Вот мой цикл, помещенный в метод run ().Функция Tick () является полезной нагрузкой цикла.Он просто содержит упорядоченные вызовы других методов, выполняющих постоянное обновление игры.
long engFPS = 40;
long frameDur = 1000 / engFPS;
long lastFrameTime;
long nextFrame;
<...>
while(true)
{
lastFrameTime = System.currentTimeMillis();
nextFrame = lastFrameTime + frameDur;
Tick();
if(nextFrame - System.currentTimeMillis() > 0)
{
try
{
Thread.sleep(nextFrame - System.currentTimeMillis());
}
catch(Exception e)
{
System.err.println("TSEngine :: run :: " + e);
}
}
}
Основная проблема в том, что Thread.sleep просто любит предавать ваши ожиданияо том, сколько он будет спать.Он может легко перевести поток в режим ожидания гораздо дольше или намного короче, особенно на некоторых компьютерах с Windows XP (я сам это проверял, WinXP дает действительно неприятные результаты по сравнению с Win7 и другими ОС).Я довольно много разыскивал в интернете, и результат был разочаровывающим.Кажется, это ошибка планировщика потоков той ОС, в которой мы работаем, и его так называемая гранулярность.Насколько я понял, этот планировщик постоянно в течение определенного времени проверяет требования каждого потока в системе, в частности выводит / выводит их из спящего режима.Когда время повторной проверки мало, например, 1 мс, все может показаться плавным.Хотя говорят, что WinXP имеет степень детализации до 10 или 15 мс.Я также читал, что с этой проблемой сталкиваются не только программисты на Java, но и те, кто использует другие языки.Зная это, кажется почти невозможным сделать стабильный, крепкий, надежный игровой движок.Тем не менее, они везде.Мне очень интересно, с помощью чего можно решить эту проблему или обойти ее.Может ли кто-нибудь более опытный дать мне подсказку на это?