Breakout Collision: обнаружение стороны столкновения

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;  

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

Я провел последние несколько дней, слоняясь вокруг, но я потерян.

user590903
источник

Ответы:

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

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

MichaelHouse
источник
1
Но как бы вы использовали это, чтобы изменить положение игрока, поскольку игрок перемещается внутри кирпича, будет выполнено несколько таких условий, и если вы сбросите желаемый x на край стены, например, если он нажмет клавишу кирпича установить желаемый х точно рядом со стеной, тогда он не будет работать, потому что когда вы проверяете теоретическое положение персонажа, чтобы увидеть, в каком направлении он сталкивается, будет выполнено несколько из этих условий, так как бы вы используйте это для сброса плеера, вам нужно добавить еще в конце каждого if)?
блюджайке
Насколько я знаю, "игрок" в игре типа прорыв - это весло. Весло не движется внутри кирпича, и вы не меняете положение весла, основываясь на взаимодействии шара с кирпичом. Если это то, что вы делаете, вам не нужна дополнительная логика, просто не обрабатывайте репозицию, пока не выполните все проверки столкновений. Или верните, как только одна из проверок верна.
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/

Густаво Масиэль
источник