вторник, 27 октября 2015 г.

Передвижение от одной точке к другой

В играх часто нужно осуществить передвижение из точки А в точку Б. Тем более для игр с видом "сверху". Вот лучшее решение что я нашел.


So let's say you start with these values: start and end mark the end points of the movement, speed is how many pixels it should move by second, and elapsed is the rate at which you'll update your object's position (some engines already provide that value for you):

Vector2 start = new Vector2(x1, y2);
Vector2 end = new Vector2(x2, y2);
float speed = 100;
float elapsed = 0.01f;
 
The first thing you'll want to calculate is the distance between both points, and a normalized vector containing the direction from start to end. Also, you should "snap" the object position to the start point. This step is done only once, at the beginning:

float distance = Vector2.Distance(start, end);
Vector2 direction = Vector2.Normalize(end - start);
object.Position = start;
moving = true;
 
Then on your update method, you move the object by adding a multiplication of direction, speed and elapsed to its position. After that, to check if the movement is over, you see if the distance between the start point and the object's current position is greater than the initial distance you calculated. If that's true, we snap the object's position to the end point, and stop moving the object:

if(moving == true)
{
    object.Position += direction * speed * elapsed;
    if(Vector2.Distance(start, object.Position) >= distance)
    {
        object.Position = end;
        moving = false;
    }
}
 
--- 
Единственное moving я не использую, а сравниваю текущую позицию с заданной целью. 
Если они не равны, то двигаемся к цели.
 
Вот пример: 
if (!currentPosition.equals(targetPosition)) {
    Vector2 newPosition = new Vector2(currentPosition).add(calculateVelocity(delta));

    if (!checkBounds(newPosition)) {
        setTargetPosition(currentPosition);
        return;
    }

    setCurrentPosition(newPosition);

    if (currentPosition.dst(startPosition) >= distanceToTarget)
        setCurrentPosition(targetPosition);
}