Обнаружение столкновения путем скольжения по плоскости в XNA - PullRequest
6 голосов
/ 14 января 2011

Я пытаюсь разработать алгоритм обнаружения столкновений для пользовательского клиента Minecraft, который я создаю. По сути, весь мир состоит из кубиков, и игрок (или камера) должен уметь стоять и двигаться против этих кубиков. Результат, который я хочу, показан на этом рисунке: image

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

Надеюсь, я прояснил свой вопрос. Каков наилучший и наиболее эффективный способ внедрения системы обнаружения столкновений, подобной этой? Кроме того, будет ли такая система учитывать простой гравитационный компонент?

РЕДАКТИРОВАТЬ: Забыл упомянуть, кубы хранятся в трехмерном массиве, [x, y, z].

Ответы [ 2 ]

1 голос
/ 14 января 2011

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

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

По сути, вы должны разбить обнаружение столкновений на 2 фазы, обычно известные как широкая фаза иузкая фаза.

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

0 голосов
/ 15 января 2011

В мире выровненных по оси кубов это действительно просто. Легко думать, что вам нужно что-то сложное, но на самом деле это действительно просто. Это из опыта после написания моего собственного клона Minecraft.

Вот как:

position.X += velocity.X;
if(colliding())
  position.X -= velocity.X;

position.Y += velocity.Y;
if(colliding())
  position.Y -= velocity.Y;

position.Z += velocity.Z;
if(colliding())
  position.Z -= velocity.Z;

Вот код для определения, сталкиваетесь вы или нет:

bool colliding()
{
  int minX = Position.X - size.X / 2;
  int minY = Position.Y - size.Y / 2;
  int minZ = Position.Z - size.Z / 2;

  int maxX = Position.X + size.X / 2;
  int maxY = Position.Y + size.Y / 2;
  int maxZ = Position.Z + size.Z / 2;

  for (int x = minX; x <= maxX; x++)
    for (int y = minY; y <= maxY; y++)
      for (int z = minZ; z <= maxZ; z++)
      {
        if(blockType[x, y, z] != 0)
          return true;
      }

   return false;
}
...