2010-03-26 5 views
2

Я использую Box2dx с C#/XNA. Я пытаюсь написать функцию, которая определяет, если тело может существовать в данной точке, не сталкиваясь ни с чем:Box2dx: Использование World.QueryAABB?

/// <summary> 
    /// Can gameObject exist with start Point without colliding with anything? 
    /// </summary> 
    internal bool IsAvailableArea(GameObjectModel model, Vector2 point) 
    { 
     Vector2 originalPosition = model.Body.Position; 
     model.Body.Position = point; // less risky would be to use a deep clone 

     AABB collisionBox; 
     model.Body.GetFixtureList().GetAABB(out collisionBox); 

     // how is this supposed to work? 
     physicsWorld.QueryAABB(x => true, ref collisionBox); 

     model.Body.Position = originalPosition; 
     return true; 
    } 

Есть ли лучший способ пойти об этом? Как работает World.QueryAABB?

Это более ранняя попытка. Это сломано; он всегда возвращает false.

/// <summary> 
    /// Can gameObject exist with start Point without colliding with anything? 
    /// </summary> 
    internal bool IsAvailableArea(GameObjectModel model, Vector2 point) 
    { 
     Vector2 originalPosition = model.Body.Position; 
     model.Body.Position = point; // less risky would be to use a deep clone 

     AABB collisionBox; 
     model.Body.GetFixtureList().GetAABB(out collisionBox); 

     ICollection<GameObjectController> gameObjects = worldQueryEngine.GameObjectsForPredicate(x => ! x.Model.Passable); 

     foreach (GameObjectController controller in gameObjects) 
     { 
      AABB potentialCollidingBox; 
      controller.Model.Body.GetFixtureList().GetAABB(out potentialCollidingBox); 

      if (AABB.TestOverlap(ref collisionBox, ref potentialCollidingBox)) 
      { 
       model.Body.Position = originalPosition; 
       return false; // there is something that will collide at this point 
      } 
     } 
     model.Body.Position = originalPosition; 
     return true; 
    } 

ответ

4

World.QueryAABB объявлен как это:

public void QueryAABB(Func<Fixture, bool> callback, ref AABB aabb) 

В качестве второго параметра вы передадите ось выровнена ограничительной рамки интересующего вас, естественно.

В качестве первого параметра необходимо передать делегат типа Func<Fixture, bool>. Если вы не знакомы с делегатами, вы можете замалчивать их на данный момент: считайте это ключом, что вам нужно передать либо: a) существующую функцию в вашем коде, либо b) новую функцию, которую вы можете объявить «на лету», если тебе нравится.

Когда вы вызываете QueryAABB, он перезвонит вам каждый раз, когда находит объект, который перекрывает ограничивающий прямоугольник, который вы предоставляете. Если он обнаружит три объекта, перекрывающие ограничивающий прямоугольник, он будет вызывать вашу функцию три раза, один раз на объект. Каждый раз, когда вы можете вернуть true, скажите «спасибо, продолжайте поиск» или false, чтобы сказать «это хорошо, больше не искать».

Так один пример использования будет:

private bool m_foundCount = 0; 

internal bool IsAvailableArea(GameObjectModel model, Vector2 point) 
{ 
    ... 
    m_foundCount = 0; 
    physicsWorld.QueryAABB(OnFoundSomething, ref collisionBox); 
    Debug.WriteLine(string.Format("Found {0} fixtures in total", m_foundCount)); 
    .. 
} 

internal bool OnFoundSomething(Fixture found) 
{ 
    Debug.WriteLine(string.Format("Found fixture {0}", found)); 
    ++m_foundCount; 
    return true; // true to carry on searching, false when done 
} 

(Как и в сторону, это имело обыкновение быть даже больше, в более ранних версиях C# требуется вам явно обернуть делегат вокруг OnFoundSomething, а-ля:

physicsWorld.QueryAABB(new Func<Fixture, bool>(OnFoundSomething), ref collisionBox); 

к счастью, это и связанной с ними синтаксис больше не требуется вообще.)

другой способ сделать это с лямбда-функции, которая является математик Speak для безымянная функция, которую вы определяете «на лету».

Эквивалент лямбда-функция к функции выше OnFoundSomething является:

found => 
{ 
    Debug.WriteLine(string.Format("Found fixture {0}", found)); 
    ++m_foundCount; 
    return true; 
} 

Таким образом, единственное отличие состоит в том, что функция не имеет имя, и тип его возвращаемого значения и аргументов отработаны из контекст, в котором вы его используете. Как и в:

internal bool IsAvailableArea(GameObjectModel model, Vector2 point) 
{ 
    ... 
    m_foundCount = 0; 
    physicsWorld.QueryAABB(found => 
    { 
     Debug.WriteLine(string.Format("Found fixture {0}", found)); 
     ++m_foundCount; 
     return true; 
    }, ref collisionBox); 
    Debug.WriteLine(string.Format("Found {0} fixtures in total", m_foundCount)); 
    .. 
} 

Что касается ваших ранее попыток, я не уверен, но я подозреваю, что это, возможно, было возвращение ложного всего времени, потому что вы перебираете все игровые объекты, в том числе и вы тестирование; следовательно, это было бы «сталкиваться» с самим собой.

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

  • Нет связанных вопросов^_^