Показать сообщение отдельно
Старый 30.01.2013, 23:02
KumoKairo вне форума Посмотреть профиль Отправить личное сообщение для KumoKairo Найти все сообщения от KumoKairo
  № 1  
Ответить с цитированием
KumoKairo
 
Аватар для KumoKairo

Регистрация: Jan 2013
Сообщений: 550
Записей в блоге: 1
Post Переменный шаг перемещения и ускорение (Variable time step). Алгоритм

Доброго времени суток.
Многодневные поиски информации и экспериментирования не дали результатов, поэтому попробую тут спросить, может кто сталкивался.

Суть:
Есть игра-платформер, создаваемая во FlashDevelop с помощью Starling. То есть нет гарантированного количества FPS, есть только ограничение сверху (стандартные для Stage3D 60 FPS).

Поэтому обычную модель перемещения (Fixed time step), когда каждый кадр к позиции игрока прибавляется или убавляется определенное значение перемещения, использовать нельзя.
Еще интересней - простую реализацию Variable time step, когда каждый кадр проверяется время, прошедшее с последнего отрисованного кадра, и это значение умножается на нашу квантовую скорость, которая уже прибавляется к положению игрока, тоже использовать нельзя.
Причина - движение с ускорением.
Допустим мы нажали клавишу "Влево". Пока она нажата, мы предполагаем, что игрок движется влево. Проверяем, не привысил ли он установленный лимит (не разогнался ли до предельного значения)
Код AS3:
if (Math.abs(this.player.xSpeed) < this.atmoshpere.linearSpeed && !this.player.inAir)
Если нет, то увеличиваем скорость игрока на величину, которая зависит от прошедшего времени:
Код AS3:
this.player.xSpeed -= elapsed * this.atmoshpere.linearSpeedIncrement;
Тут явно заметна проблема - при низких FPS игрок просто не сможет разогнаться до нормальной скорости, поскольку ограничивающее значение абсолютно.
Можно попытаться связать ограничивающую скорость с прошедшим временем,
Код AS3:
if (Math.abs(this.player.xSpeed) < this.atmoshpere.linearSpeed*elapsed && !this.player.inAir)
Но тогда в случае, если FPS резко возрастет, допустим, с 30 FPS до 60, скорость игрока уже будет больше, чем позволяет в данном случае ограничение
Код AS3:
 this.atmoshpere.linearSpeed*elapsed
Решение простое - добавить условие, при котором, если скорость игрока больше вычисленного только что лимита, присвоить игроку максимально возможную в данной ситуации скорость:
Код AS3:
if (Math.abs(this.player.xSpeed) > this.atmoshpere.linearSpeed * elapsed)
{
	this.player.xSpeed = - this.atmoshpere.linearSpeed * elapsed;
}
Но теперь игрок начинает дергаться, резко замедляться, поскольку часто FPS не очень стабильно (меняется +/- на 3 кадра в секунду)

В общем основная проблема с этим ограничителем максимальной скорости, из-за него весь сыр-бор.

значение elapsed измеряется в миллисекундах (изменялось от 16 до 150), скорости linearSpeed и linearSpeedIncrement меньше единицы, первое ограничено 0.2, второе 0.005

Давно откладываю решение этой проблемы, но в скором времени уже надо разобраться..

Понимаю, что нужен какой-то совершенно новый, другой подход, но самому поменять устоявшийся образ в голове довольно трудно)
Может кто-то сталкивался с подобной проблемой?
Заранее спасибо


Последний раз редактировалось KumoKairo; 31.01.2013 в 01:40.