Sofia IA

Inteligência artificial para jogos

Steering Behaviors – Pursuit e Evade

fazer um comentário »

O comportamento Pursuit faz com que um agente (perseguidor/pursuer) corra atrás de outro (fugitivo/evader), mas usa a posição futura estimada do fugitivo para calcular a trajetória que o perseguidor irá fazer. O evader é o comportamento contrário, ao invés de ir até a posição futura, o fugitivo tenta evita-la.

Pursuit e Evade

Não houve grande mistério na implementação desses algoritmos. O único detalhe é que dessa vez tanto o alvo, quanto o veículo são membros da classe veículo.

Abaixo, segue o código do pursuit:


namespace behavior
{
   class Pursuit : public SteerForce
   {
      private:
         const Vehicle& vehicle;
         const Vehicle& evader;

      public:
         Pursuit(const Vehicle& _vehicle, const Vehicle& _evader)
         : vehicle(_vehicle), evader(_evader)
         {
         }

         virtual math::Vector2D calculate()
         {
            //if the evader is ahead and facing the agent then we can just seek
            math::Vector2D toEvader =
               evader.getPosition() - vehicle.getPosition();

            if ((toEvader.dot(vehicle.getVelocity()) > 0) &&
                (vehicle.getVelocity().dot(evader.getVelocity()) < 0.95))
               return Seek<math::Vector2D>(vehicle, evader.getPosition()).
                        calculate();

            //Not considered ahead, so we predict where the evader will be

            //the look-ahead time is proportional to the distance between the
            //evader and the vehicle; and it's inversely proportional to the
            //sum of the agents velocities.
            double lookAheadTime = toEvader.getSize() /
               (vehicle.getMaxSpeed() + evader.getVelocity().getSize());

            //now seek to the predicted future position of the evader
            return Seek<math::Vector2D>(vehicle, evader.getPosition() +
               evader.getVelocity() * lookAheadTime).calculate();
         }
   };

E do Evade:

namespace behavior
{
   class Evade : public SteerForce
   {
      private:
         const Vehicle& vehicle;
         const Vehicle& pursuer;

      public:
         Evade(const Vehicle& _vehicle, const Vehicle& _pursuer)
         : vehicle(_vehicle), pursuer(_pursuer)
         {
         }

         virtual math::Vector2D calculate()
         {
            math::Vector2D toPursuer =
               pursuer.getPosition() - vehicle.getPosition();

            //the look-ahead time is proportional to the distance between the
            //pursuer and the vehicle; and it's inversely proportional to the
            //sum of the agents velocities.
            double lookAheadTime = toPursuer.getSize() /
               (vehicle.getMaxSpeed() + pursuer.getVelocity().getSize());

            //now flee away from predicted future position of the pursuer
            return Flee<math::Vector2D>(vehicle, pursuer.getPosition() +
               pursuer.getVelocity() * lookAheadTime).calculate();
         }
   };
}

Uma das chaves para esses algoritmos é a função que estima a posição futura.  Uma idéia interessante talvez seja parametrizar essa função, através de um functor e manter como padrão a função acima. Assim, uma implementação mais precisa poderia levar em consideração mais características físicas dos agentes envolvidos; tais como a velocidade de rotação, aceleração e frenagem; ou mesmo características do cenário, para obter-se um comportamento ainda mais convincente.

Escrito por vinigodoy

05 dUTC Fevereiro dUTC 2008 às 13:04:30

Deixe uma resposta