Столкновения игровых объектов с полом из-за силы тяжести?
-
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 : Продвинутая физика персонажей . Это упрощает уравнения обновления физики (не нужно отслеживать скорость!) И упрощает столкновения (не нужно регулировать скорость!). Тем не менее, у него есть несколько нюансов , если вам нужна точность. р>
Одним из наиболее полных учебников по этому предмету является Обнаружение столкновений в реальном времени от Кристера Эриксона . У него есть сопутствующий блог . Математика для программирования 3D-игр и компьютерной графики тоже полезно.
Я специально не занимаюсь программированием игр, но это мое понимание:
- в идеальном мире с "бесконечной частотой кадров" вы бы обнаружили столкновение точно в тот момент, когда оно произошло, и использовали немного стандартной физики для моделирования новых скоростей и ускорений тел после столкновения (см. Стандартный учебник механики средней школы или различные книги, озаглавленные "Физика для игровых программистов")
- на самом деле, поскольку у вас фиксированная частота кадров и, следовательно, тела перемещаются только с определенной степенью детализации, вам обычно нужно добавить дополнительный трюк, например, заранее вычислить относительный путь, по которому тела будут перемещаться в следующем кадре, и посмотреть, пересекается ли какой-либо из путей
- если они действительно пересекаются, то точка пересечения фактически будет оценка, но немного неточно указывает точку, в которой тела действительно столкнулись бы;затем у вас есть выбор: наплевать и принять эту оценку за точку пересечения и линейно интерполировать, чтобы получить скорости в точке столкновения, или выполнить более точный расчет теперь, когда вы выяснили, что они будут пересекаться, чтобы получить фактическую точку / время / скорости столкновения
В дополнение к моделированию столкновений, хорошим подходом является также моделирование продолжающихся передач энергии (или импульса, или просто скорости, в зависимости от сложности вашего моделирования). Когда ваш игрок стоит на платформе, сохраняйте эту информацию в объекте, представляющем платформу, и каждый раз, когда скорость объекта регулируется, вы можете напрямую применить это изменение к таким образом связанным игроку или другим объектам.