Как заставить игрока плавно перемещаться по местности

diagram

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

Мне кажется, что я почти там, но я не могу положить последнюю часть на место.

Обновление: отличные новости! У меня есть работа. Но ... Я немного смущен тем, что я должен нормализовать, а что нет. Нормальный просто должен быть единичным вектором, не так ли? но тогда я смешиваю это с моим вводом, поэтому я нормализую это - я не прав?

Кстати, я также обнаружил, что мне нужно нажать 1 пиксель игрока в направлении нормали, чтобы они не зацикливались на вещах - хорошо работает.

10 голосов | спросил Iain 23 rdEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 23 Sep 2010 21:35:27 +0400 2010, 21:35:27

2 ответа


13

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

Vector undesiredMotion = normal * (dotProduct(input, normal));
Vector desiredMotion = input - undesiredMotion;

Что-то в этом роде. Хотя на вашей прекрасной диаграмме вход кажется подальше от стены, поэтому я немного смущен.

ответил Chris Howe 23 rdEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 23 Sep 2010 21:47:24 +0400 2010, 21:47:24
1

В то время как прямолинейно просто удалить компонент движения, который находится в направлении нормали, это может подойти вашему игровому процессу, чтобы вместо этого повернуть вектор движения. Например, в игре с участием 3-го лица может быть легко слегка подвешивать стены и другие границы, поэтому вы можете сделать некоторые догадки о том, что намерен игрок.

// assume that 'normal' is unit length
Vector GetDesired(Vector input, Vector normal) {
   // tune this to get where you stop when you're running into the wall,
   // vs. bouncing off of it
   static float k_runningIntoWallThreshold = cos(DEG2RAD(45));

   // tune this to "fudge" the "push away" from the wall
   static float k_bounceFudge = 1.1f;

   // normalize input, but keep track of original size
   float inputLength = input.GetLength();
   input.Scale(1.0f / inputLength);

   float dot = DotProduct(input, normal);

   if (dot < 0)
   {
      // we're not running into the wall
      return input;
   }
   else if (dot < k_runningIntoWallThreshold)
   {
      Vector intoWall = normal.Scale(dot);
      intoWall.Scale(k_bounceFudge);

      Vector alongWall = (input - intoWall).Normalize();
      alongWall.Scale(inputLength);

      return alongWall;
   }
   else
   {
      // we ran "straight into the wall"
      return Vector(0, 0, 0);
   }
}
ответил dash-tom-bang 23 rdEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 23 Sep 2010 23:41:33 +0400 2010, 23:41:33

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132