2017-01-09 4 views
1

В настоящее время я работаю над 2D-игровым движком на C# с использованием GDI + и добрался до точки, где хочу добавить простое обнаружение столкновения.Физический движок (обнаружение столкновений C#, GDI +)

До сих пор, я могу проверить, является ли мой игрок пересекается с другим объектом игры, используя код ниже:

public static bool IntersectGameObject(GameObject a, GameObject b) 
{ 
    Rectangle rect1 = new Rectangle((int)a.Position.X, (int)a.Position.Y, a.Sprite.Bitmap.Width, a.Sprite.Bitmap.Height); 
    Rectangle rect2 = new Rectangle((int)b.Position.X, (int)b.Position.Y, b.Sprite.Bitmap.Width, b.Sprite.Bitmap.Height); 

    return rect1.IntersectsWith(rect2); 
} 

Это фантастика, и я рад, что я получил это далеко, однако я хотите узнать, пересекался ли мой игрок с верхней, нижней, левой или правой стороной игрового объекта, чтобы я мог остановить движение моего игрока в этом направлении, если ... он сталкивается со стеной. Как мне это сделать? Может кто-нибудь, пожалуйста, помогите мне :)

Кстати, игровые объекты имеют Bitmaps, которые все 32 * 32 пикселей, поэтому мне не нужно за столкновения пикселей

Спасибо заранее :)

ответ

2

Вычислительный ли два прямоугольника пересекаются лишь вопрос нескольких сравнений (я знаю, что вы уже используете IntersectsWith):

if (Left > other.Right) return false; 
if (Right < other.Left) return false; 
if (Top > other.Bottom) return false; 
if (Bottom < other.Top) return false; 
return true; 

Чтобы определить направление удара, вы должны принять во внимание возможность:

  • один прямоугольник полностью содержит другие (сталкиваетс не в направлении)
  • это может создать «мн.ч. нас»фигура (наталкивается во всех направлениях)
  • один угол прямоугольника может пересекаться с углом другого угла (сталкивается в двух направлениях)

Во всяком случае, чтобы определить, был ли он столкнулся с левой стороны:

if (Right > other.Left && Right < other.Right && Left < other.Left) 
{ 
    // the right side of "this" rectangle is INSIDE the other 
    // and the left side of "this" rectangle is to the left of it 
} 

И последнее, но не в последнюю очередь, если вы вычисляя этот кадр за кадром, есть вероятность того, что объект может «перепрыгнуть» с другой стороны. Для более реалистичной физики вам нужно будет отслеживать время и вычислять , когда будет пересекаться с (каждым краем) прямоугольника.

+0

Хотя я назвал это лучшим ответом, я решил не идти по этому маршруту. Однако ваш ответ чрезвычайно информативен. –

0

Если вам требуется обнаружение столкновений, вам нужно твердое тело, вы обычно двигаете жесткие тела с физикой. Насколько я понял, это может быть проблема с приведенным выше фрагментом кода. Если вы перемещаете их с преобразованием, вы должны пометить как кинематический. Это означает, что он не будет перемещен физикой, а преобразован.

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

, если вы хотели бы знать, с какой стороны вы попали вы можете raycast к объекту

Этот фрагмент кода дает пример, который показывает raycast можно выполнить при столкновении. В конечном счете, какой игровой движок вы используете?

//this ray will generate a vector which points from the center of 
//the falling object TO object hit. You subtract where you want to go from where you are 

Ray MyRay = ObjectHit.position - ObjectFalling.position; 


//this will declare a variable which will store information about the object hit 
raycasthit MyRayHit; 

//this is the actual raycast 
raycast(MyRay, out MyRayHit); 

//this will get the normal of the point hit, if you dont understand what a normal is 
//wikipedia is your friend, its a simple idea, its a line which is tangent to a plane 

vector3 MyNormal = MyRayHit.normal; 

//this will convert that normal from being relative to global axis to relative to an 
//objects local axis 

MyNormal = MyRayHit.transform.transformdirection(MyNormal); 

//this next line will compare the normal hit to the normals of each plane to find the 
//side hit 

if(MyNormal == MyRayHit.transform.up) 
{ 
you hit the top plane, act accordingly 
} 
//important note the use of the '-' sign this inverts the direction, -up == down. Down doesn't exist as a stored direction, you invert up to get it. 

if(MyNormal == -MyRayHit.transform.up) 
{ 
you hit the bottom plane act accordingly 
} 
if(MyNormal == MyRayHit.transform.right) 
{ 
hit right 
} 
//note the '-' sign converting right to left 
if(MyNormal == -MyRayHit.transform.right) 
{ 
hit left 
} 
+0

Вы, должно быть, не видели, как я прочитал все свое сообщение, я пишу свой собственный движок игры в C#, используя GDI + –

+0

Извините, я не понял это предложение «Я сейчас работаю над 2D-игровым движком в C#», так как «Я в настоящее время разрабатываю 2D-движок в C#» – nuriselcuk

0

Не было бы возможность иметь 4 различных объекты каждую один на 1 сторону на вашем объект игрока поэтому, в зависимости с какой сторона пересекается с игровым объектом, который вы могли бы знать, какие движения направления предотвратить?

0

Если вы обрабатываете кадр за кадром, хорошим выбором может быть сохранение предыдущей позиции P0x,P0y и текущей позиции P1x,P1y.

enter image description here

Затем вы можете вычислить вектор Vx, Vy, и вы можете вычислить точку пересечения Ix,Iy. Таким образом, вы можете получить более точную информацию о столкновении.

Смежные вопросы