Столкновения игровых объектов с полом из-за силы тяжести?

StackOverflow https://stackoverflow.com/questions/437676

  •  22-07-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

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

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

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

Так как мы это сделаем? Вы отслеживаете, сколько времени прошло с момента последнего вызова метода Update. Я создал 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's velocity vector
        gameObject.position.x += (gameObject.velocity.x * elapsedSeconds); 
        gameObject.position.y += (gameObject.velocity.y * elapsedSeconds);

    }

    checkCollisions();

    previousTime = currentTime;
}

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

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

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

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

Другие советы

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

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

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

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

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

scroll top