2010-04-07 148 views
0

我正在使用Box2d - Box2dx的XNA端口在C#中编写XNA游戏。Box2d:设置活动和不活动

树木或僵尸等实体表示为GameObjects。 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()之前,此方法已被调用很多次。我觉得这可能会搞砸了。

+0

是controller.Model.Body一个box2d对象? – HyperCas 2010-04-07 15:55:58

+0

这完全正确。 – 2010-04-07 16:55:54

回答

1

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

其次,“Body”对象...它可能会覆盖equals方法,在这种情况下,执行“==”时可能会得到奇怪的结果。如果你真的在寻找相同的实例(它是一个类),你可以使用object.ReferenceEquals方法。

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