Подтвердить что ты не робот

Столкновения между игровыми объектами и полом в отношении силы тяжести?

Как игры с гравитацией управляют отношениями между движущимися вещами, такими как игроки, монстры или объекты и пол? Неужели игрок постоянно "падает" на пол и возвращается обратно?

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

4b9b3361

Ответ 1

Возможно, вы захотите проверить "Часто задаваемые вопросы о гравитации" GameDev.net для некоторой базовой информации.

Поскольку вы создаете игру, а не очень точный физический модельер, мы можем уйти с интеграции Euler. Если ваша потребность в точности увеличивается, самым популярным методом интеграции, который я использую, является интеграция Runge-Kutta (RK4). Скорее всего, вам это не понадобится для простой игры, но они определенно используются в более продвинутом физическом моделировании и 3D-играх. Недостаток использования RK4 несколько усложняется и немного медленнее. Это очень точно, хотя, но пока, давайте придерживаться хорошего ole Euler.

Я задал аналогичный вопрос: "Как применить гравитацию к моей прыгающей игре в мяч" и получил несколько хороших ответов. Первое, что вы сделаете, это выбрать произвольную гравитационную константу для вашей игры. В моем приложении отбойного шара я использую стандартную гравитационную константу 2000px/s. Вы хотите играть с этой постоянной силы тяжести, чтобы получить желаемый эффект для вашей конкретной игры.

Затем вы хотите удостовериться, что вы делаете свою игру и самостоятельно обновляете свои игровые объекты. Это необходимо для того, чтобы ваши внутриигровые объекты быстро перемещались на быстрых компьютерах и замедлялись на медленных компьютерах. Вам нужна физика и скорость, с которой ваши объекты перемещаются, чтобы быть независимыми от скорости компьютера. Хорошая статья об этом - Игровая физика: исправьте свой timestep!.

Итак, как мы это делаем? Вы отслеживаете, сколько времени прошло с момента последнего вызова метода обновления. Я создал 2 потока, хотя это не обязательно. У меня есть поток обновления игры и поток рендеринга. Нить обновления контролирует обновление позиций в игровых объектах. Нить обновления знает, когда она была ранее вызвана, текущее время и от нее вычисляет прошедшее время с момента вызова метода обновления.

Чтобы применить гравитацию, мы просто добавим к скорости Y нашего объекта по нашей постоянной силы тяжести, умноженной на прошедшее время.

private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;

public void updateGame()
{
    currentTime = System.currentTimeMillis();
    float elapsedSeconds = (currentTime - previousTime) / 1000f; 

    foreach(GameObject gameObject in gameObjects)
    {
        // Apply gravity to velocity vector
        gameObject.velocity.y += (gravityConstant * elapsedSeconds); 

        // Move objects x/y position based off it velocity vector
        gameObject.position.x += (gameObject.velocity.x * elapsedSeconds); 
        gameObject.position.y += (gameObject.velocity.y * elapsedSeconds);

    }

    checkCollisions();

    previousTime = currentTime;
}

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

Чтобы ответить на ваш другой вопрос, да, объекты будут постоянно иметь "силу" силы тяжести на своем векторе y. Поэтому он будет постоянно сталкиваться с полом. Тем не менее, одна вещь, которую вы хотите сделать, это использовать значение Epsilon, чтобы в конечном итоге привести вашу скорость gameObject к нулю. Затем, во время обнаружения столкновения как части процесса обрезки, вы можете, как правило, пропускать проверку, если не движущийся объект сталкивается с чем-либо (не наоборот, хотя!).

То, что мне нравится делать с столкновениями, - это когда я нахожу объекты, сталкивающиеся (проникающие друг в друга), я раздвигаю их на минимальное расстояние передачи (MTD), которое их разделяет. Этот шаг является ключевым, иначе вы получите часто наблюдаемую ошибку в играх объектов, "застрявших" вместе, дрожащих движений. Когда они разделены, я вычисляю свой ответ на столкновение.

Используя этот метод, он будет отлично работать в описываемом сценарии восходящей платформы. Платформа будет продолжать расти, gameObject будет отделяться, используя MTD между собой и платформой, и она, естественно, будет расти вместе с ней.

Если вам нужна помощь в ответе на столкновение, я бы предложил посмотреть:

Ответ 2

Один подход, используемый в некоторых играх, - обмануть: иметь отдельное состояние для ходьбы и в воздухе. Во время ходьбы игровой движок может определить наклон поверхности пройденной и, если не слишком крутой, перемещать символ в направлении поверхности, а также придавать персонажу правильное вертикальное расположение относительно поверхности.

Что касается физики, я становлюсь фанатом интеграции вербов, как описано в Gamasutra: Advanced Character Physics. Это упрощает уравнения физического обновления (не нужно отслеживать скорость!), И это упрощает коллизии (не нужно настраивать скорость!). Тем не менее, если вам нужна точность, несколько нюансов.

Ответ 4

Я не специально программист игр, но это мое понимание:

  • в идеальном мире с "бесконечной частотой кадров" вы обнаружите столкновение именно в тот момент, когда оно произошло, и используйте немного стандартной физики для моделирования новых скоростей и ускорений тел после столкновения (см. стандартный учебник по механике средней школы или различные книги под названием "Физика для программистов Игр" ).
  • в действительности, поскольку у вас есть фиксированная частота кадров, и, следовательно, тела движутся только с определенной детализацией, вам обычно нужно добавить дополнительный трюк, например, заранее рассчитывать относительный путь, по которому тела будут перемещаться по следующему кадру и видеть если какой-либо из путей пересекает
  • если они пересекаются, то точка пересечения будет фактически оценкой, но немного неточной, точки, в которой тела действительно столкнулись бы; тогда у вас есть выбор не заботиться и принимать эту оценку как точку пересечения и линейно интерполировать, чтобы получить скорости в точке столкновения, или сделать более точный расчет, теперь вы обнаружили, что они будут пересекаться, чтобы получить фактическая точка/время/скорости столкновения

Ответ 5

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