我正在使用Box2d的XNA端口 - Box2dx在C#中编写XNA游戏。
树或僵尸等实体表示为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);
}
controllers
是GameObjectController
个实例的集合。
worldState.Models
是GameObjectModel
个实例的集合。
当我以这种方式从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 :(得分:1)
一些事情。该错误实际上来自Single方法,因为它假定序列中至少有一个项目。如果您想要更宽容的行为,请使用SingleOrDefault,它将返回该类型的默认值(如果它是一个类,则为null)。
其次,“Body”对象......它可能会覆盖equals方法,在这种情况下,在执行“==”时可能会得到奇怪的结果。如果您确实在寻找相同的实例(并且它是一个类),您可以使用object.ReferenceEquals
方法。
第三,你应该重新考虑你的设计。任何时候你必须遍历一个集合来寻找一个给定的项目(这是所有.Where方法都有)你有机会使用更好的算法