以恒定速度从A(x,y)移至B(x1,y1)吗?


21

我目前有类似的东西:

float deltaX = point0.getX() - point1.getX();
float deltaY = point0.getY() - point1.getY();

每隔0.01秒,我就会刷新对象位置,如下所示:

object.setPosition(object.getX()-deltaX/100,object.getY()-deltaY/100);

因此,这会在1秒内将我的对象从point0移动到point1。我需要的是2个点,以便能够将对象从point0移动,以恒定的速度面向point1。因此,当我有一个点更接近我的初始点时,对象将以与我拥有一个更远点时相同的速度向它移动。任何建议表示赞赏。谢谢。


可能重复的内容:gamedev.stackexchange.com/questions/23430/… 我会发布与其他问题相同的答案。但这对我来说是无耻的。
Gustavo Maciel

Answers:


26

我将使用一些线性代数结构,因为这样更容易描述操作。如果您不知道如何实现这些矢量操作,我将在最后给出快速解释。

因此,假设您从这些值开始:startend标记运动的终点,speed它是每秒应移动多少像素,以及elapsed更新对象位置的速率(某些引擎已经为您提供了该值):

Vector2 start = new Vector2(x1, y2);
Vector2 end = new Vector2(x2, y2);
float speed = 100;
float elapsed = 0.01f;

您要计算的第一件事是两点之间的距离,以及包含从开始到结束的方向的归一化向量。另外,您应该将对象位置“捕捉”到该start点。在开始时,此步骤仅执行一次:

float distance = Vector2.Distance(start, end);
Vector2 direction = Vector2.Normalize(end - start);
object.Position = start;
moving = true;

然后,您的更新方法,可以通过添加的乘法移动对象directionspeedelapsed给它的位置。之后,要检查移动是否结束,请查看起点和对象当前位置之间的距离是否大于您计算出的初始距离。如果是这样,我们将对象的位置捕捉​​到终点,然后停止移动该对象:

if(moving == true)
{
    object.Position += direction * speed * elapsed;
    if(Vector2.Distance(start, object.Position) >= distance)
    {
        object.Position = end;
        moving = false;
    }
}

快速向量运算参考

表示

Vector2 A = float aX, aY;

加/减

A+B = a.x + b.x; a.y + b.y;
A-B = a.x - b.x; a.y - b.y;

乘以标量(浮点)

A*float = a.x*float; a.y*float;

长度/距离

length(A) = sqrt(a.x*a.x + a.y*a.y)
distance(A,B) = length(B-A)

归一化

normalize(A) = a.X/length(A); a.Y/length(A);

如果您没有Vector可用的类,则足以将上述代码转换为常规操作。


转换示例

// Your Variables
float startX, startY, endX, endY;
float speed = 100;
float elapsed = 0.01f;

// On starting movement
float distance = Math.sqrt(Math.pow(endX-startX,2)+Math.pow(endY-startY,2));
float directionX = (endX-startX) / distance;
float directionY = (endY-startY) / distance;
object.X = startX;
object.Y = startY;
moving = true;

// On update
if(moving == true)
{
    object.X += directionX * speed * elapsed;
    object.Y += directionY * speed * elapsed;
    if(Math.sqrt(Math.pow(object.X-startX,2)+Math.pow(object.Y-startY,2)) >= distance)
    {
        object.X = endX;
        object.Y = endY;
        moving = false;
    }
}

1
@Fofole这就是为什么我在最后给出向量的解释的原因。答案应该是通用的。如果没有Vector类,则使用两个单独的浮点数。例如Vector2 start;变为float startX, startY;。就像我在最后解释的那样,您可以轻松地手动计算距离。即float dX = bX - aX; float dY = bY - aY; float distance = Math.sqrt(dx*dx+dy*dy);
David Gouveia'2

@Fafole检查编辑,我添加了一个示例。不知道我是否错过了什么。
David Gouveia'2

3年后,您让我了解了如何使用矢量移动对象。干杯!
奥利弗·舍宁(OliverSchöning),2015年

3

创建一个Vector并将其规范化。警告,前面带有错误数字的伪代码:

Vector = new Vector(point0.getX() - point1.getX(), point0.getY() - point1.getY());

这将为您提供一个Vector,例如:

25.96; 85.41

现在将向量归一化,您将收到以下消息

0.12; 0.75

从这里开始,与您的三角洲运动相同。


2

从我的答案复制并粘贴到:在两点之间的直线上获取点

在伪代码中:

speed_per_tick = 0.05 //constant speed you want the object to move at
delta_x = x_goal - x_current
delta_y = y_goal - y_current
goal_dist = sqrt( (delta_x * delta_x) + (delta_y * delta_y) )
if (dist > speed_per_tick)
{
    ratio = speed_per_tick / goal_dist
    x_move = ratio * delta_x  
    y_move = ratio * delta_y
    new_x_pos = x_move + x_current  
    new_y_pos = y_move + y_current
}
else
{
    new_x_pos = x_goal 
    new_y_pos = y_goal
}

这个答案最适合我的用例。
外壳
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.