2016-08-16 3 views
1

Я сформулировал свою собственную систему столкновений в модифицированной версии OpenTK. Он работает, запустив цикл foreach, который проверяет все квадратики в игре (это происходит, когда что-то движется), и устанавливает свою позицию обратно туда, где это был последний кадр, то есть если он пересекает этот кадр. Возможно, я не так хорошо объяснил, так вот код SetXVelocity, который называется, когда игрок движется вправо.Столкновение пропускает определенные квадраты

public void SetXVelocity(float x) 
     { 
      foreach (Quad quad in quads) 
      { 
       if (!quad.Equals(this)) 
       { 
        if (Intersects(quad)) 
        { 
         Velocity.x = 0; 
         Position = OldPosition; 
         continue; 
        } 
        if (!Intersects(quad)) 
        { 
         OldPosition = Position; 
         Velocity.x = x; 
         continue; 
        } 
       } 
       else 
       { 
        OldPosition = Position; 
        continue; 
       } 
       OldPosition = Position; 
       continue; 
      } 
     } 

Вот код для Intersects:

public bool Intersects(Quad quad) 
     { 
      #region 
      if (TLCorner.x > quad.TLCorner.x && TLCorner.x < quad.BRCorner.x && TLCorner.y < quad.TLCorner.y && TLCorner.y > quad.BRCorner.y) 
      { 
       return true; 
      } 
      if (BRCorner.x < quad.BRCorner.x && BRCorner.x > quad.TLCorner.x && BRCorner.y > quad.BRCorner.y && BRCorner.y < quad.TLCorner.y) 
      { 
       return true; 
      } 
      if (TRCorner.x < quad.TRCorner.x && TRCorner.x > quad.BLCorner.x && TRCorner.y < quad.TRCorner.y && TRCorner.y > quad.BLCorner.y) 
      { 
       return true; 
      } 
      if (BLCorner.x > quad.BLCorner.x && BLCorner.x < quad.TRCorner.x && BLCorner.y > quad.BLCorner.y && BLCorner.y < quad.TRCorner.y) 
      { 
       return true; 
      } 
      #endregion // Corner Intersection 
      if (Math.Round(Left, 2) == Math.Round(quad.Right, 2) && TRCorner.y > quad.TRCorner.y && BRCorner.y < quad.BRCorner.y) 
       return true; 
      if (Math.Round(Right, 2) == Math.Round(quad.Left, 2) && TRCorner.y > quad.TRCorner.y && BRCorner.y < quad.BRCorner.y) 
       return true; 
      return false; 
     } 

Кстати, TRCorner является Vector3, представляющий верхний правый угол и т.д.

Последний блок кода в Quad класс, держать в виду, фактический класс огромен, поэтому я постараюсь не включать все это:

public Vector3 Velocity; 
public Vector3 Position; 
public int Index; 
public VBO<Vector3> VertexData 
    { 
     get; 
     set; 
    } 
    public VBO<int> VertexCount 
    { 
     get; 
     set; 
    } 
    public VBO<Vector2> VertexTexture 
    { 
     get; 
     set; 
    } 

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

+1

у меня не было терпения, чтобы посмотреть на все кода, но в лучшем случае ваш код пересечения выглядит слишком сложным. Для проверки соответствия двух прямоугольников и сопоставления 22 совпадений в вашем коде требуется 4 сравнения. Если у вас проблемы с логикой, вам не сложно найти код в Интернете. Это довольно легко, хотя если вы начнете думать об этом. Подсказка: по крайней мере для меня легче записать 4 условия, в которых прямоугольники не ** перекрываются, а затем отрицают логическое выражение. –

+0

Хм ... Ты меня заставил понять. Я позабочусь об этом позже, но я действительно хочу знать, почему это не работает, даже если это слишком сложно.Реальность такова, что я разрабатываю игровой движок с OpenGL, и здесь код упрощается ** много ** из того, что есть в VS. Спасибо за комментарий, хотя @RetoKoradi. –

+0

Попробуйте что-то более простое, например https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection. Плеер придерживается их, потому что вы используете '>' и '<', поэтому к моменту проверки столкновения прямоугольники внутри друг друга и сталкиваются навсегда. – Harish

ответ

0

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

С вашего && все ваши условия, столкновение должно соответствовать всем вашим условиям, чтобы их обнаружить.

if (TLCorner.x > quad.TLCorner.x && TLCorner.x < quad.BRCorner.x && TLCorner.y < quad.TLCorner.y && TLCorner.y > quad.BRCorner.y) 
     { 
      return true; 
     } 

if(TLCorner.x == quad.TLCorner.x && TLCorner.y < quad.TLCorner.y && TLCorner.y > quad.BRCorner.y) прямоугольник все еще сталкивается, но незамеченной.

То же самое для других условий.

Возможно, вы захотите использовать в своем коде >= и <=, чтобы охватить все условия.

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

Также, возможно, вы захотите поменять скорость и «не застрять» их при обнаружении столкновения таким образом, чтобы они не застревали в других соседних прямоугольниках.

Я настоятельно рекомендую вам использовать более логику для обнаружения столкновений

Ссылка: https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection

Вы можете проверить его здесь http://jsfiddle.net/knam8/

+0

Я переключился на этот метод в ссылке, с> =, и это все еще происходит. –

+0

Я предлагал '> =' и '<=' для вашего кода, не используйте его для кода в ссылке, я думаю, что код работает так, как есть. Вы можете протестировать его здесь http://jsfiddle.net/knam8/ – Harish

+0

Хорошо, я дам ему шанс, когда вернусь на свой компьютер –

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