0

我正在使用 Box2d - Box2dx 的 XNA 端口用 C# 编写 XNA 游戏。

像树或僵尸这样的实体被表示为游戏对象。GameObjectManager在游戏世界中添加和删除它们:

    /// <summary>
    /// Does the work of removing the GameObject.
    /// </summary>
    /// <param name="controller">The GameObject to be removed.</param>
    private void removeGameObjectFromWorld(GameObjectController controller)
    {
        controllers.Remove(controller);
        worldState.Models.Remove(controller.Model);
        controller.Model.Body.SetActive(false);
    }

    public void addGameObjectToWorld(GameObjectController controller)
    {
        controllers.Add(controller);
        worldState.Models.Add(controller.Model);
        controller.Model.Body.SetActive(true);
    }

controllersGameObjectController实例的集合。

worldState.ModelsGameObjectModel实例的集合。

当我以这种方式从 Box2d 中删除 GameObjects 时,会调用此方法:

       void IContactListener.EndContact(Contact contact)
        {
            GameObjectController collider1 = worldQueryUtils.gameObjectOfBody(contact.GetFixtureA().GetBody());
            GameObjectController collider2 = worldQueryUtils.gameObjectOfBody(contact.GetFixtureB().GetBody());
            collisionRecorder.removeCollision(collider1, collider2);
}

世界查询工具:

    // this could be cached if we know bodies never change
    public GameObjectController gameObjectOfBody(Body body)
    {
        return worldQueryEngine.GameObjectsForPredicate(x => x.Model.Body == body).Single();
    }

此方法会引发错误:

System.InvalidOperationException was unhandled
  Message="Sequence contains no elements"
  Source="System.Core"
  StackTrace:
       at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
       at etc

为什么会这样?我能做些什么来避免它?这个方法在被调用之前已经被调用了很多次body.SetActive()。我觉得这可能搞砸了。

4

1 回答 1

1

一些东西。该错误实际上来自 Single 方法,因为它假定序列中至少有一项。如果您想要更宽容的行为,请使用 SingleOrDefault 它将返回该类型的默认值(如果它是一个类,则为 null)。

其次,“Body”对象......它可能重写了equals方法,在这种情况下,执行“==”时可能会得到奇怪的结果。如果您实际上是在寻找相同的实例(并且它是一个类),则可以使用该object.ReferenceEquals方法。

第三,你应该重新考虑你的设计。任何时候你必须遍历一个集合来寻找一个给定的项目(这是所有 .Where 方法所做的)你有机会使用更好的算法

于 2010-04-09T19:33:45.353 回答