Прорив зіткнення: виявлення сторони зіткнення


10

Я пишу проривний клон (моя перша гра) і повністю застряг, як я з'ясував, в яку сторону цегла потрапила.

У мене є метод виявлення зіткнень, який виглядає приблизно так:

DetectCollision(Object a, Object b)

   x = distance(a.x, b.x);
   y = distance(a.y, b.y);

   if (x is smaller than the combined width &  y is smaller is than combined height {
       return true;
   }
return false;  

Це працює цілком чудово, але мені потрібно знати сторону зіткнення та розташування відносно центру, щоб правильно реагувати.

Я провів останні кілька днів, ковтаючи, але розгубився.

Відповіді:


13

Це все можна виділити з положення кулі відносно положення цегли, в яку вона зіткнулася.

Виявивши зіткнення:

if(ballPosition.y <= brickPosition.y - (brickHeight/2))
  //Hit was from below the brick

if(ballPosition.y >= brickPosition.y + (brickHeight/2))
  //Hit was from above the brick

if(ballPostion.x < brickPosition.x)
  //Hit was on left

if(ballPostion.x > brickPosition.x)
  //Hit was on right

Перші дві перевірки, щоб бачити, чи кулька знаходиться над цеглою або нижче. Якщо ні це не повинно бути поруч із цеглою, тож перевірте, на якій стороні знаходиться. Це потрібно буде налаштувати, щоб відповідати тому, звідки ви приймаєте місцезнаходження, тобто цеглаPosition - це центр цегли або цеглаPosition - це верхній лівий кут.


1
Але як би ви використали це для перестановки гравця, оскільки гравець переміщується всередині цегли, буде дотримано кілька цих умов, і якщо ви скинете потрібний х на край стіни, наприклад, якщо він натиснув клавішу цегли встановити потрібний х прямо біля стіни, тоді він би не справді працював, тому що, коли ви перевірите теоретичне положення персонажа, щоб побачити, з якого напрямку він стикається, буде виконано кілька цих умов, то як би ви використовуйте це для скидання програвача, чи потрібно додавати ще в кінці кожного, якщо)?
bluejayke

Наскільки я знаю, «гравець» у грі типу прориву - це весло. Весло не рухається всередині цегли, і ви не змінюєте положення весла на основі взаємодії кулі з цеглою. Якщо це те, що ви робите, вам не потрібна додаткова логіка, просто не обробляйте зміни, поки ви не зробите всі перевірки зіткнення. Або повернутися, як тільки один із чеків буде правдивим.
MichaelHouse

8

Ви можете використовувати Vector Math для виявлення кутів між ними!

Ось коротка відповідь:

ballToBrick = ballPosition - brickPosition;
ballToBrick.Normalize();
brickFacing = Vector2(0,1).Normalize();


float angle = acos( Dot(ballToBrick, brickFacing) );

Облицювання цегли - це хитрий вектор, це "початкова точка" обчислення кута. і якщо ви хочете, щоб вектор вказав угору, зробіть його (0, 1), вліво (-1, 0), праворуч (1, 0), вниз (0, -1). Якщо припустити, що ви знаходитесь на осі OpenGL, де вгору та вправо позитивні.

Якщо ви не знаєте, ось визначення кожної використовуваної функції:

Vector2.Normalize()
{
    float length = squareroot(x * x + y * y);
    x = x / length;
    y = y / length;
    return this;
}

Dot(Vector2 a, Vector2 b)
{
    return a.x * b.x + a.y * b.y;
}

( https://en.wikipedia.org/wiki/Dot_product )

Довідка: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-2/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.