Сила тяжести и высота прыжка как-то зависят от частоты кадров - Pygame - PullRequest
2 голосов
/ 13 февраля 2020

Сейчас я нахожусь на ранних стадиях создания классического c 2D-платформера с использованием pygame для школьного проекта, и я экспериментировал с механизмом прыжка c, когда столкнулся с этой довольно странной проблемой. Даже при том, что я учел временную разницу между обновлениями, длина и высота прыжка оба становятся короче , когда увеличивается время между кадрами.

Здесь Я имею Позвольте 3 экземплярам объекта Player прыгать по экрану, двигаясь вправо с постоянной скоростью 700 пикселей в секунду и начальной скоростью вверх 700 пикселей в секунду. У каждого из них было искусственно увеличенное минимальное значение delta_time, равное 0,001 с, 0,017 с и 0,1 с соответственно.

Таким образом, новые векторы скорости и положения вычисляются внутри функции обновления объекта Player, которая вызывается один раз в каждом кадре. (delta_time передается из основного обновления l oop):

self.speed.y += 1000.0 * delta_time
self.position += self.speed * delta_time

И так рассчитывается delta_time в конце каждого цикла основного обновления l oop (инициализируется со значением ноль для первого кадра):

delta_time = time.time() - pre_time
pre_time = time.time()
if delta_time < min_delta_time:
    time.sleep(min_delta_time - delta_time)
    delta_time += time.time() - pre_time
    pre_time = time.time()

min_delta_time представляет минимальное время между обновлениями кадра.

После многих попыток исправить это, я почти уверен, что Недостаток лежит в линии, которая обновляет скорость, но даже после двойной проверки математики я все еще не могу понять, в чем проблема. Сначала я подумал, что это может быть неточное время delta_time, но если бы это было так, горизонтальная скорость также пострадает, и трассы все равно будут выстраиваться.

Так что я могу изменить что-нибудь, чтобы совершить прыжок / гравитация более последовательная?

1 Ответ

2 голосов
/ 13 февраля 2020

Это не ошибка в кодировании, а скорее логическая ошибка в модели: при моделировании ускорения, которое происходит мгновенно в точках обновления, а не непрерывно в течение полного промежутка времени, вводятся неточности, которые становятся больше, чем меньше обновления.

Чтобы проиллюстрировать это, рассмотрим объект, ускоряющийся со скоростью 1 м / с ^ 2 от остановки. Если мы смоделируем это, как описано выше, с интервалом в 1 секунду, через шесть секунд наша модель установит объект на 21м. Повторяя с 2-секундным интервалом, мы установим его на 24 м, а с 3-секундным интервалом - 27 м. Однако реальное положение должно составлять 18 м.

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

Таким образом, ваша логика обновления c станет примерно такой:

self.speed.y += 500.0 * delta_time
self.position += self.speed * delta_time
self.speed.y += 500.0 * delta_time
...