2010-03-26 13 views
0

Je fais du pathfinding où j'utilise la force pour pousser le corps vers les waypoints. Cependant, une fois qu'ils sont assez près du waypoint, je veux annuler la force. Comment puis-je faire ceci? Dois-je maintenir séparément toutes les forces que j'ai appliquées au corps en question? J'utilise Box2dx (C#/XNA).Box2dx: Annuler la force sur un corps?

Voici ma tentative, mais il ne fonctionne pas du tout:

internal PathProgressionStatus MoveAlongPath(PositionUpdater posUpdater) 
    { 
     Vector2 nextGoal = posUpdater.Goals.Peek(); 
     Vector2 currPos = posUpdater.Model.Body.Position; 
     float distanceToNextGoal = Vector2.Distance(currPos, nextGoal); 
     bool isAtGoal = distanceToNextGoal < PROXIMITY_THRESHOLD; 

     Vector2 forceToApply = new Vector2(); 
     double angleToGoal = Math.Atan2(nextGoal.Y - currPos.Y, nextGoal.X - currPos.X); 
     forceToApply.X = (float)Math.Cos(angleToGoal) * posUpdater.Speed; 
     forceToApply.Y = (float)Math.Sin(angleToGoal) * posUpdater.Speed; 

     float rotation = (float)(angleToGoal + Math.PI/2); 

     posUpdater.Model.Body.Rotation = rotation; 

     if (!isAtGoal) 
     { 
      posUpdater.Model.Body.ApplyForce(forceToApply, posUpdater.Model.Body.Position); 
      posUpdater.forcedTowardsGoal = true; 
     } 

     if (isAtGoal) 
     { 
      // how can the body be stopped? 

      posUpdater.forcedTowardsGoal = false; 
      //posUpdater.Model.Body.SetLinearVelocity(new Vector2(0, 0)); 
      //posUpdater.Model.Body.ApplyForce(-forceToApply, posUpdater.Model.Body.GetPosition()); 
      posUpdater.Goals.Dequeue(); 

      if (posUpdater.Goals.Count == 0) 
      { 
       return PathProgressionStatus.COMPLETE; 
      } 
     } 

MISE À JOUR

Si je fais garder la trace de la quantité de force que j'ai appliqué, il ne tient pas compte pour d'autres forces qui peuvent agir dessus.

Je pourrais utiliser la réflexion et régler _force directement à zéro, mais cela semble sale.

Répondre

0

Si vous voulez juste arrêter le corps mort (annulant toutes les forces qui agissent sur lui), vous pouvez simplement mettre en veille:

posUpdater.Model.Body.SetAwake(false) 

Cela vide linéaire et les forces angulaires et les vitesses du corps. Les corps de couchage n'entrent pas en collision avec d'autres corps endormis et prennent généralement moins de temps CPU, car leur physique est désactivé.

Si vous voulez réellement le corps à prendre part à la physique une fois qu'il est arrêté mort, juste réveiller immédiatement:

posUpdater.Model.Body.SetAwake(false) 
posUpdater.Model.Body.SetAwake(true) 

Cela peut conduire à la recherche « contre nature » résultats si le corps était au milieu d'entrer en collision avec d'autres choses bien sûr.