Arrive steering behavior

Posted by dbostream on Game Development See other posts from Game Development or by dbostream
Published on 2012-11-25T11:13:47Z Indexed on 2012/11/25 11:24 UTC
Read the original article Hit count: 341

Filed under:
|

I bought a book called Programming game AI by example and I am trying to implement the arrive steering behavior. The problem I am having is that my objects oscillate around the target position; after oscillating less and less for awhile they finally come to a stop at the target position. Does anyone have any idea why this oscillating behavior occur? Since the examples accompanying the book are written in C++ I had to rewrite the code into C#. Below is the relevant parts of the steering behavior:

private enum Deceleration
{
    Fast = 1,
    Normal = 2,
    Slow = 3
}

public MovingEntity Entity { get; private set; }

public Vector2 SteeringForce { get; private set; }

public Vector2 Target { get; set; }

public Vector2 Calculate()
{
    SteeringForce.Zero();

    SteeringForce = SumForces();

    SteeringForce.Truncate(Entity.MaxForce);

    return SteeringForce;
}

private Vector2 SumForces()
{
    Vector2 force = new Vector2();

    if (Activated(BehaviorTypes.Arrive))
    {
        force += Arrive(Target, Deceleration.Slow);

        if (!AccumulateForce(force))
            return SteeringForce;
    }

    return SteeringForce;
}

private Vector2 Arrive(Vector2 target, Deceleration deceleration)
{
    Vector2 toTarget = target - Entity.Position;

    double distance = toTarget.Length();

    if (distance > 0)
    {
        //because Deceleration is enumerated as an int, this value is required
        //to provide fine tweaking of the deceleration..
        double decelerationTweaker = 0.3;

        double speed = distance / ((double)deceleration * decelerationTweaker);

        speed = Math.Min(speed, Entity.MaxSpeed);

        Vector2 desiredVelocity = toTarget * speed / distance;

        return desiredVelocity - Entity.Velocity;
    }

    return new Vector2();
}

private bool AccumulateForce(Vector2 forceToAdd)
{
    double magnitudeRemaining = Entity.MaxForce - SteeringForce.Length();

    if (magnitudeRemaining <= 0)
        return false;

    double magnitudeToAdd = forceToAdd.Length();

    if (magnitudeToAdd > magnitudeRemaining)
        magnitudeToAdd = magnitudeRemaining;

    SteeringForce += Vector2.NormalizeRet(forceToAdd) * magnitudeToAdd;

    return true;
}

This is the update method of my objects:

public void Update(double deltaTime)
{
    Vector2 steeringForce = Steering.Calculate();

    Vector2 acceleration = steeringForce / Mass;

    Velocity = Velocity + acceleration * deltaTime;

    Velocity.Truncate(MaxSpeed);

    Position = Position + Velocity * deltaTime;
}

If you want to see the problem with your own eyes you can download a minimal example here.

Thanks in advance.

© Game Development or respective owner

Related posts about c#

Related posts about steering-behaviors