shpaker
@shpaker
Вольный хлебопашец

Как организовать игровые циклы?

Вот интересует вопрос организации игровых циклов.
Хочется что бы обновление состояния, не зависело от обновления картинки. И обновление картинки, желательно не было фиксированным.
Из хорошего материала нашёл только вот такую статью на Хабре: Игровые циклы или ЭлектроКардиоГама.
  • Вопрос задан
  • 4922 просмотра
Пригласить эксперта
Ответы на вопрос 4
Обновление картинки в js весим на requestAnimationFrame.

Из-за однопоточной сути js вместо цикла
while(game_is_running){
  update_game();
  sleep(time);
}

для обновления модели используем таймеры с поправкой, что-то в стиле
var update = Date.now();
function f(){
  var last = update;
  update_game();
  update = Date.now();
  if(game_is_running) setTimeout(f, time - update + last);
}
f();
Ответ написан
Комментировать
Хочется что бы обновление состояния, не зависело от обновления картинки. И обновление картинки, желательно не было фиксированным.

Так в статье об этом ведь и говорится (кстати, спасибо за статью).
Если вас интересует реализация на конкретной платформе, то это довольно общий вопрос, зависит от того, конкретно какой части цикла он касается:
1) Ну, по части состояния, думаю нет, т.к. тут всё замешано на языке.
2) Если по части отрисовки - это уже зависит только от платформы, и доступных для неё графических библиотек.
Ответ написан
@Nadoedalo
К комменту Rock - так же не стоит забывать о том что Javascript не точен во времени, так что в игру стоит прибавить зависимость переменных(кулдаун, передвижение) к количеству прошедших миллисекунд.
Ответ написан
Комментировать
Teivaz
@Teivaz
Не знаю ка обстоит дело с играми на JS, но на C++ в функцию update передаётся время с прошлого апдейта, как правило, в милисекундах. Это время удобно учитывать для перемещения объекта.
void update(float dt)
{
float traveled = getSpeed() * dt + getTravaledDistance();
setTraveledDistance(traveled);
}

При этом функция отрисовки и функция обновления выполняются в одном потоке (иначе нужно будет синхронизировать потоки, лочить некоторые методы и т.д.).
А если игра вдруг подвисла, то в апдейт может прийти довольно большое значение времени и тогда игровые элементы могут сделать резкий скачок. Чтобы избавиться от этого можно обрезать максимально возможное время в главном цикле:
// main loop
while(!done)
{
float dt = getTimeSinceLastUpdate();
dt = min(33.3, dt); // equals 30 fps
update(dt);
render();
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы