2013-12-11 3 views
0

У меня странная проблема с BoundingBox и тем, что в make. Для цикла не работает корректно и вызывает проблемы, которые не изменяют переменную.Что-то странное с BoundingBox в XNA

for (int i = 0; i < thing.Length; i++) 
     { 
      for (int j = 0; j < thing.Length; j++) 
      { 
       if (thing[i].bb.Intersects(thing[j].bb) && i != j) 
       { 
        thing[i].spriteSpeed *= -1; 
        thing[j].spriteSpeed *= -1; 
        soundEffect.Play(0.2f, -1f, 0f); 
       } 
      } 
     } 

Но если я изменю переменную j на статическое число, как и на нуль, код будет работать нормально.

for (int i = 0; i < thing.Length; i++) 
     { 
      for (int j = 0; j < thing.Length; j++) 
      { 
       if (thing[i].bb.Intersects(thing[0].bb) && i != 0) 
       { 
        thing[i].spriteSpeed *= -1; 
        thing[0].spriteSpeed *= -1; 
        soundEffect.Play(0.2f, -1f, 0f); 
       } 
      } 
     } 

P.S. Thing - это структура, которая выглядит так:

struct Thing 
    { 
     public Texture2D myTexture; 
     public Vector2 spritePosition; 
     public Vector2 spriteSpeed; 
     public BoundingBox bb; 
     public Vector3 start, end; 
    } 
+0

Tnx Corey. Он отлично работает для меня. – Rincew1nd

ответ

0

Проблема в том, что вы обновляете оба объекта одновременно.

Рассмотрите случай, когда у вас есть два элемента в списке, и их ограничивающий прямоугольник перекрываются. Проходя через петлю вы получите:

i == 0, j == 0: Skip because (i == j) 
i == 0, j == 1: Reverse direction of [0] and [1] 
i == 1, j == 0: Reverse direction of [1] and [0] 
i == 1, j == 1: Skip because (i == j) 

Работу через последовательность вы обращенно элементы дважды, возвращая их в исходные рубрики.

Чтобы предотвратить это, и попутно сократить количество испытаний, необходимых для обработки полного списка объектов, переменная j всегда должен начинаться 1 выше, чем i, так как все сравнения для i <= j либо уже сделаны или являются недействительными.

Попробуйте этот код вместо:

for (int i = 0; i < thing.Length; i++) 
{ 
    for (int j = i + 1; j < thing.Length; j++) 
    { 
     if (thing[i].bb.Intersects(thing[j].bb)) 
     { 
      thing[i].spriteSpeed *= -1; 
      thing[j].spriteSpeed *= -1; 
      soundEffect.Play(0.2f, -1f, 0f); 
     } 
    } 
} 

Это имеет эффект сокращения количества сравнений примерно в два раза (на самом деле (n^2-n)/2 если мы быть точным), а также удаление всех двойных разворотов. Каждая возможная комбинация элементов в списке проверяется только один раз.

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