2010-11-20 5 views
1

У меня есть простая схема столкновения с прямоугольной черепицей, и она прекрасно работает.Предотвращение туннелирования с помощью этой настройки?

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

В основном моя установка выглядит следующим образом:

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

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

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

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

Может ли кто-нибудь дать мне руку?

ответ

3

Я предполагаю, что ваш код для перемещения игрока из сталкивающейся плитки делает это за один шаг. Поэтому, если игрок сталкивается с плиткой, вы определяете, что глубина проникновения равна 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; 
    } 
} 

То есть простой вариант, если вы не подстраиваясь к ellaped времени. Если вы, то вы достаточно выполнить меньшее время действия

Так

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 пикселю.

+0

Попытаться осуществить это, вернется к вам. Благодаря! –

+0

Он работает, работает: 3 –