Aiming at Player in Farseer (Box2D)

This is done by using the Raycast function in Box2D. You cast a ray between the enemy and the player. If it collides with an object then it will enter the function. At this stage you can examine the object or fixture it has hit by looking at the userdata attribute to see if you are seeing the ground first before the player. In which case do not fire.

This firing function fires at the last location the enemy was at, you can offset this to fire a bit in front but again you need to analyse where the player is. It was easier for me just to have more than one firing enemy. That way the player is being fired at from different locations so one of the shots should hit.

world.RayCast((f, p, n, fr) =>
                                {
                                    if (fr < minfraction)
                                    {
                                        minfraction = fr;
                                        closestfixture = f;
                                        return -1;
                                    }
                                    else
                                        return -1;
                                    }, dicEnemy[pair.Key].body.Position, agent.body.Position);

As you can see a ray is cast from each enemy towards the player. Below is the code where you examone the fixture and calculate the distance

if (closestfixture != null && (String)closestfixture.Body.UserData != "Ground")
   {
        dicEnemy[pair.Key].bTarget = true;
        double a = Math.Pow(agent.body.LinearVelocity.X, 2) + Math.Pow(agent.body.LinearVelocity.Y, 2) – Math.Pow(dicEnemy[pair.Key].ProjectTileSpeed, 2);
        double b = 2 * (agent.body.LinearVelocity.X * (agent.Position.X – dicEnemy[pair.Key].Position.X) + agent.body.LinearVelocity.Y * (agent.Position.Y – dicEnemy[pair.Key].Position.Y));
        double c = Math.Pow(agent.Position.X – dicEnemy[pair.Key].Position.X, 2) + Math.Pow(agent.Position.Y – dicEnemy[pair.Key].Position.Y, 2);
        double disc = Math.Pow(b, 2) – 4 * a * c;
        double t2 = (-b – Math.Sqrt(Math.Abs(disc))) / (2 * a);

 

That radians code listed below calculates the angle at which the missile should be fired.

 

Vector2 aimSpot = agent.Position + agent.body.LinearVelocity * (float)ConvertUnits.ToSimUnits(Math.Abs(t2));

                                      float radians = (float)Math.Atan2(aimSpot.X – dicEnemy[pair.Key].Position.X, aimSpot.Y – dicEnemy[pair.Key].Position.Y);

Below is a full listing of the code

world.RayCast((f, p, n, fr) =>
   {
    if (fr < minfraction)
    {
       minfraction = fr;
       closestfixture = f;
       return -1;
    }
    else
       return -1;
    }, dicEnemy[pair.Key].body.Position, agent.body.Position);
    //  if (closestfixture != null && (String)closestfixture.UserData != "Ground")
    if (closestfixture != null && (String)closestfixture.Body.UserData != "Ground")
    {
        dicEnemy[pair.Key].bTarget = true;
        double a = Math.Pow(agent.body.LinearVelocity.X, 2) + Math.Pow(agent.body.LinearVelocity.Y, 2) – Math.Pow(dicEnemy[pair.Key].ProjectTileSpeed, 2);
        double b = 2 * (agent.body.LinearVelocity.X * (agent.Position.X – dicEnemy[pair.Key].Position.X) + agent.body.LinearVelocity.Y * (agent.Position.Y – dicEnemy[pair.Key].Position.Y));
        double c = Math.Pow(agent.Position.X – dicEnemy[pair.Key].Position.X, 2) + Math.Pow(agent.Position.Y – dicEnemy[pair.Key].Position.Y, 2);
        double disc = Math.Pow(b, 2) – 4 * a * c;
        double t2 = (-b – Math.Sqrt(Math.Abs(disc))) / (2 * a);
        Vector2 aimSpot = agent.Position + agent.body.LinearVelocity * (float)ConvertUnits.ToSimUnits(Math.Abs(t2));
        float radians = (float)Math.Atan2(aimSpot.X – dicEnemy[pair.Key].Position.X, aimSpot.Y – dicEnemy[pair.Key].Position.Y);
        Vector2 distancevect = aimSpot – dicEnemy[pair.Key].Position;
        if (aimSpot.X – dicEnemy[pair.Key].Position.X < 0)
              dicEnemy[pair.Key].bleft = true;
              float aimdistance = distancevect.Length();

              if (dicEnemy[pair.Key].bhit==false && dicEnemy[pair.Key].body != null && currValue.bshoot.Equals(true) && (aimdistance < 7))
              {
                 /* Missile Code goes here */
                 shoteffect.play()

Advertisements

Tags: ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: