Search code examples
c#xna2dphysicsmonogame

Following point using force


I'm trying to make my Entity.cs Follow(Vector2 point) any point in the map. This has to be done using "force". Force is a Vector2 of Entity that is used to move the Entity across the map. On every Update(float elapsedTime) of Entity, Entity is moved by Force * elapsedTime. Like this:

public virtual void Update (float elapsedTime)
{
    position += force * elapsedTime;
}

So, I want to create a function similar to Update function, called Follow, which will be adding enough force to the Entity so that it moves to the point, and stops when it reaches that point.

This could be used by bullet class (child of Entity) to follow an enemy, or something like that, I beleave you can all see what I'd use that for in the game.

Currently, the code looks like this:

public virtual void Follow (Vector2 follow, float intensity)
{
    if (position != follow) AddForce((follow - position) * intensity);
    else AddForce(-force);
}

And the code calling this function looks like this

Follow(followThisPoint, 300 * elapsedTime);

Note that this line is called on every Update, and that is how I'd like to be.

The problem I'm having with this function is that too much force is added to the entity, and it just passes right trough the point where I want it to be, and then, when it passes, it slows down, and tries to go back, but then I get the same result I just described, but in opposite direction.

I'd like to have control of how fast the Entity will follow the point of interest, and to have it stop instantly at the point of interest, or slow down when near, and stop on that point slowly.

Edit 1: As requested, here is the AddForce function:

public void AddForce (Vector2 addForce)
{
    force += addForce;
}

Solution

  • Before I answer the question, I want to clarify some terminology.

    Your variable force is actually a velocity. It represents how fast an object travels. A force can change an object's velocity via acceleration. If you apply a force to an object, this object is accelerated. The effect on the velocity depends on how long the force is applied and on the object's mass.

    Given that, let's take a look at your question. You want to apply a force, such that the resulting velocity vector is:

    vTarget = (follow - position) * intensity
    

    This implies that the velocity drops to zero when the object reaches the target. You can also limit the velocity to an upper bound.

    Given your AddForce definition, you have to apply the following force F:

    vTarget            = vCurrent + F
    vTarget - vCurrent = F
    

    Again, you can limit the length of F. And this is all there is. Here is some C#/pseudo code:

    public virtual void Follow (Vector2 follow, float intensity)
    {
        float vMax = 1000;
        float fMax = 1000;
        Vector2 vTarget = (follow - position) * intensity;
        if (vTarget.Length() > vMax) vTarget = vTarget * (vMax / vTarget.Length());
        Vector2 force = vTarget - this.force; //where this.force is actually the velocity
        if (force.Length() > fMax) force = force * (fMax / force.Length());
        AddForce(force);
    }