2015-07-12 3 views
-2

В настоящее время я делаю небольшую консольную игру. В конце игрового цикла есть еще один цикл, который не будет выпущен до 1/100 секунд после начала итерации.Игровые часы и сон (C++)

Конечно, что израсходовал много ресурсов процессора, поэтому я поместил

Sleep(1); 

в конце, чтобы решить эту проблему. Я думал, что все было правильно, пока я не запустил игру на ноутбуке 2005 XP ... и это было очень медленно.

Когда я удалил команду Sleep, игра отлично работала на обоих компьютерах, но теперь у меня проблема с загрузкой процессора.

У кого-нибудь есть хорошее решение для этого?

+0

Какая же причина для вызова 'Sleep (1)' снова, пожалуйста? –

+0

Я хочу, чтобы одна итерация цикла игры занимала ровно 10 миллисекунд.Скажем, логика занимает 2 мс - осталось 8 мс. У меня есть цикл, который занимает эти 8 миллисекунд, но без сна он требует много CPU .. поэтому он предназначен для сокращения использования ЦП. – CrizerPL

+1

@CrizerPoland 'Я хочу, чтобы одна итерация цикла игры занимала ровно 10 миллисекунд. Удачи вам в этом. «Сон» не имеет такого разрешения. – PaulMcKenzie

ответ

0

Для этого необходимо использовать std::this_thread::sleep_for в заголовке <thread>, а также std::chrono. Может быть, что-то вроде этого:

while(...) 
{ 
    auto begin = std::chrono::steady_clock::now(); 

    // your code 

    auto end = std::chrono::steady_clock::now(); 
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin); 
    std::this_thread::sleep_for(std::chrono::milliseconds(10) - duration); 
} 

Если код не потребляет много времени, в течение одной итерации, или если каждая итерация занимает постоянное время, вы можете оставить в покое измерение и просто поставить там некоторая константа:

std::this_thread::sleep_for(std::chrono::milliseconds(8)); 
0

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

Вы должны включить библиотеку, которая сообщает время, получить текущее время в начале программы/начать цикл, а затем в конце цикла/программы сравнить разницу времени начала и текущего с сколько времени вы хотите. Если это меньше времени, которое вы хотите (скажем, 8 миллисекунд), скажите ему спать в течение минимального времени - currentTime - recordTime (переменная, которую вы установили в начале цикла)

Я сделал это для своих собственных игра в SDL2, SDL_GetTicks() просто находит количество миллисекунд, в котором была запущена программа, и «frametime» - это время в начале основного игрового цикла. Это то, как я держу свою игру в максимуме 60 кадров в секунду. Этот оператор if должен быть изменен и помещен в нижней части вашей программы.

if(SDL_GetTicks() - frametime < MINFRAMETIME) 
{ 
    SDL_Delay(MINFRAMETIME - (SDL_GetTicks() - frametime)); 
} 

Я думаю, что стандартная библиотека эквивалент будет:

if(clock() - lastCheck < MIN_TIME) 
{ 
    sleep(MIN_TIME - (clock() - lastCheck)); 
} 
+0

Я поместил маленький измеритель на игровой панели игры (я использовал clock()), и он показал 0-1ms на машине W7 и 1-2 мс на старом ноутбуке, поэтому я знал, что проблема связана с Sleep(). Я решил это уже, разместил его в ответ там – CrizerPL

1

Так я узнал, что проблема была с Windows NT (2000, XP, 2003) спать детализацию, что было около 15 мс .. если кто-то и борется с этим типом проблемы, вот как ее решить:

timeBeginPeriod(1); //from windows.h 

Вызов его один раз в начале основной функции(). Это влияет на несколько вещей, включая Sleep(), так что он фактически «спящий» для точной миллисекунды.

timeEndPeriod(1); //on exit 

Конечно, я разрабатывал игру на Windows 7 все время и думал, что все было правильно, так что, видимо, для Windows 6.0+ удалили эту проблему ... но это все равно полезно, учитывая тот факт, что многие люди до сих пор используют XP

Смежные вопросы