Предотвращение туннелирования с этой настройкой? - PullRequest
1 голос
/ 21 ноября 2010

У меня установлена ​​простая схема столкновения прямоугольника с плиткой, и она прекрасно работает.

Единственная проблема - когда вы начинаете падать с уступа. Ваша скорость достигает точки, в которой изменение Y / X каждого кадра достаточно велико, чтобы вы могли обрезать твердые объекты и испытывать затруднения.

В основном мои настройки таковы:

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

  1. Рассчитайте плитки вокруг персонажа для проверки.
  2. Проходить по плиткам, в том числе внутри ограничительных плиток.
  3. Проверьте прямоугольник столкновения игрока с каждой из этих плиток.
  4. Если есть пересечение, переместите самую большую ось ось из плитки, затем установите скорость этой оси равной 0.
  5. Продолжить проверки.

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

Мое решение: проверьте каждую позицию от позиции игрока до позиции игрока + скорость. Я застрял на этом.

Кто-нибудь может мне помочь?

1 Ответ

4 голосов
/ 21 ноября 2010

Я предполагаю, что ваш код для перемещения игрока из сталкивающейся плитки делает это за один шаг.Поэтому, если игрок сталкивается с плиткой, вы определяете, что глубина проникновения равна 5 в направлении Y, и вы немедленно корректируете положение игрока Y на -5.

Как вы предлагаете, проверяйте положение игрока на каждом шаге.Таким образом, если скорость Y равна 5, вы можете отрегулировать положение Y игроков на 1, проверить наличие столкновений, а затем повторить еще 4 раза.См. Позже для расчета времени обработки шага.Ниже приведен лишь некоторый базовый псевдокод и только в направлении Y.

player.Y += vel;
if (player.CheckCollisions())
{
  // handle collision
}

Становится

for (int i = 0; i < vel; ++i)
{
  player.Y += 1;
  if (player.CheckCollisions())
  {
    // handle collision
    break;
  }
}

Это простая версия, если вы не настраиваете на затраченное время.Если да, то вы скорее выполняете меньшие временные шаги

Итак

player.Y += vel * elapsedTime;
if (player.CheckCollisions())
{
  // handle collision
}

Становится

float currentTimeStep = 0;
Position startY = player.Y;
while (currentTimeStep < elapsedTime)
{
  currentTimeStep = Math.Min(currentTimeStep + stepDelta, elapsedTime); // You need to tune the stepDelta
  player.Y = startY + vel * currentTimeStep;
  if (player.CheckCollisions())
  {
    // handle collision
    break;
  }      
}

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

...