Если это ваше первое игровое приложение, использование многопоточности для достижения ваших результатов может оказаться более трудоемким, чем вы должны реально заниматься в своей первой игре. Синхронизация игрового цикла и цикла рендеринга в разных потоках - задача не из легких.
Как вы правильно заметили, время рендеринга может сильно повлиять на "скорость" вашей игры. Я бы посоветовал вам не делать свою игровую логику зависимой от установленного временного интервала (то есть 1/100 секунды). Сделайте его зависимым от текущего времени кадра (ну, последнее время кадра, так как вы не знаете, сколько времени займет рендеринг вашего текущего кадра).
Обычно я писал бы что-то вроде ниже (то, что я написал, это значительно упрощенно):
float Frametime = 1.0f / 30.0f;
while(1) {
game_loop(Frametime); // maniuplate objects, etc.
render_loop(); // render the frame
calculate_new_frametime();
}
Где Frametime - это рассчитанное время кадра, которое занял текущий кадр. Когда вы обрабатываете свой игровой цикл, вы используете время кадра из предыдущего кадра (поэтому установите начальное значение на что-то разумное, например, 1/30 или 1/15 секунды). Запуск его в предыдущий кадр достаточно близок, чтобы получить нужные вам результаты. Запустите ваш игровой цикл, используя эти временные рамки, а затем визуализируйте ваши вещи. Возможно, вам придется изменить логику в игровом цикле, чтобы не предполагать фиксированный интервал времени, но, как правило, исправления такого рода довольно просты.
Асинхронные циклы игры / рендеринга могут быть чем-то, что вам в конечном итоге понадобится, но это сложная проблема, которую нужно решить. Он включает в себя создание снимков объектов и соответствующих данных, помещение этих снимков в буфер, а затем передачу буфера в механизм рендеринга. Этот буфер памяти должен быть правильно распределен вокруг критических секций, чтобы избежать записи в него игрового цикла во время чтения из него цикла рендеринга. Вы должны быть уверены, что скопировали все соответствующие данные в буфер перед передачей в цикл рендеринга. Кроме того, вам придется написать логику, чтобы остановить либо игру, либо рендеринг циклов, ожидая завершения одного или другого.
Эта сложность - причина, по которой я предлагаю сначала написать ее более последовательно (если у вас нет опыта, который вы могли бы). Причина заключается в том, что сначала это «легкий» способ заставит вас узнать о том, как работает ваш код, как работает механизм рендеринга, какие данные нужны механизму рендеринга и т. Д. Знание многопоточности определенно требуется при разработке сложных игр в наши дни, но знание того, как это сделать хорошо, требует глубоких знаний о том, как игровые системы взаимодействуют друг с другом.