0

Box2d の XNA ポートである Box2dx を使用して、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);
}

worldQueryUtils:

    // 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 メソッドから発生しています。これは、シーケンス内に少なくとも 1 つの項目があると想定しているためです。より寛容な動作が必要な場合は、その型のデフォルト値を返す SingleOrDefault を使用します (クラスの場合は null)。

次に、"Body" オブジェクト ... equals メソッドがオーバーライドされている可能性があります。この場合、"==" を実行すると奇妙な結果が得られる可能性があります。文字通り同じインスタンス (およびそれがクラス) を探している場合は、object.ReferenceEqualsメソッドを使用できます。

第三に、デザインを再考する必要があります。特定のアイテムを探すためにコレクションをループする必要があるときはいつでも(.Where メソッドが行うすべてのことです)、より良いアルゴリズムを使用する機会があります。

于 2010-04-09T19:33:45.353 に答える