2010-11-09 4 views
4

Je travaille sur un jeu 2D en XNA basé sur le flocage. J'ai mis en œuvre la technique de flocage de Craig Reynold et maintenant je veux assigner dynamiquement un chef au groupe pour le guider vers une cible.Champ de vision XNA en 2D

Pour ce faire, je veux trouver un agent de jeu qui n'a pas d'autres agents en face de lui et en faire le chef de file, mais je ne suis pas sûr des mathématiques pour cela.

Actuellement, j'ai:

Vector2 separation = agentContext.Entity.Position - otherAgent.Entity.Position; 

float angleToAgent = (float) Math.Atan2(separation.Y, separation.X); 
float angleDifference = Math.Abs(agentContext.Entity.Rotation - angleToAgent); 
bool isVisible = angleDifference >= 0 && angleDifference <= agentContext.ViewAngle; 

agentContext.ViewAngle est une valeur radians que j'ai joué avec pour essayer d'obtenir l'effet escompté, mais ce principalement des résultats dans tous les agents étant assignés en tant que leaders.

Quelqu'un peut-il me diriger dans la bonne direction pour détecter si une entité est dans un "cône" de vue d'une autre entité?

+0

angleDifference> = 0 est toujours vrai, car angleDifference est le résultat d'une fonction Abs. – Empyrean

Répondre

1

Vous devez normaliser l'entrée de la fonction Atan2. Il faut aussi faire attention en soustrayant les angles car le résultat peut être en dehors de la plage pi à -pi. Je préfère utiliser des vecteurs de direction plutôt que des angles, de sorte que vous pouvez utiliser le fonctionnement du produit scalaire pour ce genre de chose car cela a tendance à être plus rapide et vous n'avez pas à vous soucier des angles en dehors de la gamme canonique.

Le code suivant devrait obtenir le résultat que vous êtes après:

double CanonizeAngle(double angle) 
    { 
     if (angle > Math.PI) 
     { 
      do 
      { 
       angle -= MathHelper.TwoPi; 
      } 
      while (angle > Math.PI); 
     } 
     else if (angle < -Math.PI) 
     { 
      do 
      { 
       angle += MathHelper.TwoPi; 
      } while (angle < -Math.PI); 
     } 

     return angle; 
    } 

    double VectorToAngle(Vector2 vector) 
    { 
     Vector2 direction = Vector2.Normalize(vector); 
     return Math.Atan2(direction.Y, direction.X); 
    } 

    bool IsPointWithinCone(Vector2 point, Vector2 conePosition, double coneAngle, double coneSize) 
    { 
     double toPoint = VectorToAngle(point - conePosition); 
     double angleDifference = CanonizeAngle(coneAngle - toPoint); 
     double halfConeSize = coneSize * 0.5f; 

     return angleDifference >= -halfConeSize && angleDifference <= halfConeSize; 
    } 
1

Je pense que vous voulez tester +/- angle, pas seulement + (par exemple angleDifference >= -ViewAngle/2 && angleDifference <= ViewAngle/2). Ou utilisez une valeur absolue.

Questions connexes