Box2d: ensemble actif et inactif
Question
J'écris un jeu XNA en C # en utilisant le port XNA de Box2d -. Box2dx
Les entités comme des arbres ou des zombies sont représentés comme GameObjects. GameObjectManager
ajoute et les retire du monde du jeu:
/// <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
est une collection d'instances de GameObjectController
.
worldState.Models
est une collection d'instances de GameObjectModel
.
Quand je retire GameObjects de Box2d cette façon, cette méthode est appelée:
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();
}
Cette méthode renvoie une erreur:
System.InvalidOperationException was unhandled
Message="Sequence contains no elements"
Source="System.Core"
StackTrace:
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at etc
Pourquoi est-ce qui se passe? Que puis-je faire pour l'éviter? Cette méthode a été appelée à plusieurs reprises avant que le body.SetActive()
a été appelé. Je pense que cela peut être déconner vers le haut.
La solution
Quelques choses. L'erreur est effectivement en provenance de la méthode simple car elle suppose qu'il y aura au moins un élément dans la séquence. Si vous voulez un comportement plus tolérant l'utilisation SingleOrDefault qui renverra la valeur par défaut de ce type (si elle est une classe, null).
En second lieu, l'objet « Body » ... il peut avoir la méthode equals substituée, dans ce cas, vous pouvez obtenir des résultats étranges lors d'un « == ». Si vous êtes à la recherche littéralement la même instance (et il est une classe), vous pouvez utiliser la méthode object.ReferenceEquals
.
Troisièmement, vous devez repenser votre conception. Chaque fois que vous avez à boucle à travers une collection pour trouver un élément donné (ce qui est tout la méthode .Lorsque ne), vous avez la possibilité d'utiliser un meilleur algorithme