1

Edit: I will summerize my question since it is very long (Thanks Len for pointing it out)

What I'm trying to find out is to get a new position of a player after an X amount of time. The following variables are known: - Speed - Length between the 2 points - Source position (X, Y) - Destination position (X, Y)

How can I calculate a position between the source and destion with these variables given?

For example:

source: 0, 0 destination: 10, 0 speed: 1

so after 1 second the players position would be 1, 0

The code below works but it's quite long so I'm looking for something shorter/more logical

======================================================================

I'm having a hard time figuring out how to calculate a new position of a player ingame.

This code is server sided used to track a player(It's a emulator so I don't have access to the clients code).

The collision detection of the server works fine I'm using bresenham's line algorithm and a raycast to determine at which point a collision happens.

Once I deteremined the collision I calculate the length of the path the player is about to walk and also the total time.

I would like to know the new position of a player each second.

This is the code I'm currently using. It's in C++ but I am porting the server to C# and I haven't written the code in C# yet.

        // Difference between the source X - destination X 
        //and source y - destionation Y
        float xDiff, yDiff;

        xDiff = xDes - xSrc;
        yDiff = yDes - ySrc;

        float walkingLength = 0.00F;

        float NewX = xDiff * xDiff;
        float NewY = yDiff * yDiff;

        walkingLength = NewX + NewY;

        walkingLength = sqrt(walkingLength);



        const float PI = 3.14159265F;
        float Angle = 0.00F;

        if(xDes >= xSrc && yDes >= ySrc)
        {
            Angle = atanf((yDiff / xDiff));
            Angle = Angle * 180 / PI;
        }
        else if(xDes < xSrc && yDes >= ySrc)
        {
            Angle = atanf((-xDiff / yDiff));
            Angle = Angle * 180 / PI;
            Angle += 90.00F;
        }
        else if(xDes < xSrc && yDes < ySrc)
        {
            Angle = atanf((yDiff / xDiff));
            Angle = Angle * 180 / PI;
            Angle += 180.00F;
        }
        else if(xDes >= xSrc && yDes < ySrc)
        {
            Angle = atanf((xDiff / -yDiff));
            Angle = Angle * 180 / PI;
            Angle += 270.00F;
        }

        float WalkingTime = (float)walkingLength / (float)speed;



        bool Done = false;
        float i = 0;
        while(i < walkingLength)
        {
            if(Done == true)
            {
                break;
            }
            if(WalkingTime >= 1000)
            {
                Sleep(1000);
                i += speed;
                WalkTime -= 1000;
            }
            else
            {
                Sleep(WalkTime);
                i += speed * WalkTime;
                WalkTime -= 1000;
                Done = true;
            }

            if(Angle >= 0 && Angle < 90)
            {
                float xNew = cosf(Angle * PI / 180) * i;
                float yNew = sinf(Angle * PI / 180) * i;

                float NewCharacterX = xSrc + xNew;
                float NewCharacterY = ySrc + yNew;
            }

I have cut the last part of the loop since it's just 3 other else if statements with 3 other angle conditions and the only change is the sin and cos.

The given speed parameter is the speed/second.

The code above works but as you can see it's quite long so I'm looking for a new way to calculate this.

btw, don't mind the while loop to calculate each new position I'm going to use a timer in C#

Thank you very much

4

1 回答 1

1

Forget the angles. Trigonometry are both code- and time-intensive. You should use vectors instead.

Here is an rewrite of your code:

float xDiff = xDes - xSrc;
float yDiff = yDes - ySrc;

// Euclidean distance from source to destination
float walkingLength = sqrt(xDiff * xDiff + yDiff * yDiff);

float WalkingTime = walkingLength / speed;

bool Done = false;
float i = 0;
while(i < walkingLength && !Done)
{
    if(WalkingTime >= 1f)
    {
        Sleep(1000);
        i += speed;
        WalkingTime -= 1f;
    }
    else
    {
        Sleep((int) (WalkingTime * 1000f));
        i += speed * WalkingTime;
        WalkingTime -= 1f;
        Done = true;
    }

    float xNew = xDiff / walkingLength * i;
    float yNew = yDiff / walkingLength * i;

    float NewCharacterX = xSrc + xNew;
    float NewCharacterY = ySrc + yNew;
}

xDiff / walkingLength will be the same as cosf(Angle * PI / 180) in your code.

于 2012-06-06T22:35:53.530 回答