Скорость основана на времени, а не FPS

Я делаю простое приложение с объектом, к которому я применяю гравитацию ..

Я не хочу, чтобы объект двигался слишком быстро / слишком медленно при изменении скорости fps, поэтому я искал способ сделать это, и я обнаружил, что мне нужно умножить скорость движения на дельту время..

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

На игровом цикле у меня есть это:

gravityRate = 0.02;
velocity.y +=  gravityRate;
objectPosition.y -= velocity.y;

Это зависит от частоты кадров в игре, конечно.

Я хочу, чтобы объект перемещался на 0,02 единицы за 16 мс,

Поэтому я попытался исправить это так:

velocity.y += (gravityRate * (delta * 1000.0) ) / (1000 / 60);

В то время как дельта * 1000 дает мне количество пройденных миллисекунд ..

Пока все хорошо, казалось, что все работает хорошо, и объект двигался с той же скоростью, хотя на более низких FPS он прыгает с большими промежутками, но это нормально.

Проблема в том, что я бы хотел, чтобы объект подпрыгивал в определенных случаях. такие как столкновение или около того,
Раньше я достигал этого, просто делая что-то вроде этого:
speed.y = -0,05;

Но теперь это не работает, ну, это работает, но снова полагается на fps.
Он увеличивается выше при более высоких скоростях FPS и ниже при низких скоростях FPS.
(Я думал, что это может быть из-за нескольких вызовов, которые собирают и снижают скорость больше, чем ожидалось, но это не так, он выполняется только один раз.)

Я пытался решить это некоторое время, но у меня все больше и больше проблем, так что я буду очень признателен за любую помощь

Спасибо

2

Решение

Рассчитайте свою скорость и положение на основе времени следующим образом:

deltaTime = currentTime - timeLastFrame    // time sins last frame
velocityDelta = deltaTime * gravityRate    // velocity change

// calculate new position with only half of the velocity change this frame
objectPosition.y -= (velocity.y + (velocityDelta / 2)) * deltaTime
velocity.y += velocityDelta

Весы должны быть адаптированы к вашим игровым настройкам.


РЕДАКТИРОВАТЬ:

Итак, поподробнее — сначала нам нужно узнать, сколько времени прошло с момента последнего:

deltaTime = currentTime - timeLastFrame    // time sins last frame

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

velocityDelta = deltaTime * gravityRate    // velocity change

Чтобы вычислить, сколько объект переместился в течение кадра, вычисляется средняя скорость в этом кадре. Это равно начальной скорости: velocity.y плюс конечная скорость: velocity.y + velocityDelta, деленное на 2, Короче говоря, это можно записать как (velocity.y + (velocityDelta / 2)), Со средней скоростью мы можем затем переместить объект, умножив его на время дельты кадра:

objectPosition.y -= (velocity.y + (velocityDelta / 2)) * deltaTime

Чтобы быть готовым к следующему кадру, нам также нужно обновить скорость:

velocity.y += velocityDelta
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]