Столкновения между игровыми объектами и полом относительно гравитации? - PullRequest
12 голосов
/ 13 января 2009

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

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

Ответы [ 5 ]

15 голосов
/ 13 января 2009

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

Поскольку вы создаете игру, а не модельер физики с высокой точностью, чем мы можем избежать интеграций Эйлера . Если ваша потребность в точности возрастает, наиболее популярный метод интеграции, который я вижу, это интеграция Рунге-Кутта (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;
}

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

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

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

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

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

2 голосов
/ 13 января 2009

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

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

1 голос
/ 13 января 2009

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

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

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

1 голос
/ 13 января 2009

Одним из наиболее полных учебников по этому предмету является Обнаружение столкновений в реальном времени от Кристера Эриксона . У него также есть сопутствующий блог . Эрика Ленгеля *1007* Математика для программирования 3D-игр и компьютерной графики тоже полезна.

...