为什么我的物体在45度时比在90度时移动得更快?


32

我的游戏中有一些物体在45度和90度时移动得更快。

每个对象都有

  • 点(x,y)的位置
  • Vector2D(x,y)方向
  • 整机速度

我在更新过程中所做的就是计算新职位:

position.x += direction.x * speed
position.y += direction.y * speed

我该如何纠正?我希望它以相同的速度在任何角度移动。


8
使用前将方向矢量归一化;问题解决了。
deceleratedcaviar

1
不得不谷歌规范化:)找到了这个有用的网站fundza.com/vectors/normalize/index.html
Jason94年

并且,如果您要使用用户输入来控制此对象,请注意按照XNA开发人员的说明锁定到12、3、6、9方向:xona.com/2010/05/03.html。它可能是您想要的(例如在RPG游戏中),也可能不是您想要的(例如在Geometry Wars风格的游戏中)。
Xonatron 2012年

在旧游戏Descent中,这是一个功能
J. Holmes

@ 32bitkid是的,另请参阅《毁灭战士》
bobobobo

Answers:


55

勾股定理可以解释为以下公式:

a² + b² = c²

在您的情况下,向右移动时,您正在使用(x:1,y:0)

c² = 1 + 0 = 1
c = sqrt(1) = 1.00

左右移动时,您使用的是(x:1,y:1)

c² = 1 + 1 = 2
c = sqrt(2) = 1.41

如您所见,对角线的长度比基轴的长度长。

正如其他人提到的那样,您应该简单地将方向矢量标准化。如果您使用XNA,则操作如下:

var normalizedDirection = direction;
normalizedDirection.Normalize();
position += normalizedDirection * speed

您的问题中,给您+1的帮助:)
马丁。

12

使用前将方向向量归一化。

正如MindWorX解释的那样,这很容易理解,如果您担心方向矢量可能会给您带来悲伤,请确保它们是单位矢量(幅度/长度为1)。

Length(Vector2(1, 1)) == 1.4142135623730951 // first hint of grief
Length(Vector2(1, 0)) == 1

Vector2(1, 1) * 2 == Vector2(2, 2)
Vector2(1, 0) * 2 == Vector2(2, 0)

Length(Vector2(2, 2)) = 2.8284271247461903 // second hint
Length(Vector2(2, 0)) = 2

如果归一化:

normal(Vector2(1, 1)) == Vector2(0.707107, 0.707107)
Length(Vector2(0.707107, 0.707107)) == 1 // perfect

14
没有帮助的答案。如果发问者知道“标准化您的方向向量”的含义,他就不会问这个问题。
克里斯托弗·约翰逊

@KristopherJohnson尚不清楚发问者不知道如何归一化向量。尽管发问者似乎足够机智,无论如何都没关系。
deceleratedcaviar 2012年

2
@KristopherJohnson:如果发问者不知道“标准化您的方向向量”是什么意思,他只需要在Google上输入该名称,附加他的语言名称并获得带有说明的代码即可。
Lie Ryan

6

您如何计算方向?如果是45度(1,1),那肯定比90度要快(1,0)

我建议您使用这样的东西:

direction.x = Math.Cos(angleInRadians);
direction.y = Math.Sin(angleInRadians);

要获得以弧度为单位的角度,您必须将度数乘以PI / 180甚至更好,请使用MathHelper。例如。

angleInRadians = 45.0 * Math.PI / 180.0; // first method
angleInRadians = MathHelper.ToRadians(45f); //second method

6

杰森

与其具有三个对象属性,

  • 点(x,y)的位置
  • Vector2D(x,y)方向
  • 整机速度

通常将方向和速度组合成速度向量要容易得多。然后,您只有两个属性,

  • 点(x,y)的位置
  • Vector2D(x,y)速度

更新位置

当您需要更新对象的位置时,它很简单:

position.x += velocity.x * Δt;
position.y += velocity.y * Δt;

Δt您的时间增量(或时差)或时间步长在哪里?

更新位置和速度

这种处理加速度(例如来自重力)的方法也非常容易。如果有加速度矢量,则可以像这样一起更新速度和位置:

position.x += (velocity.x * Δt) + (0.5 * acceleration.x * Δt * Δt);
position.y += (velocity.y * Δt) + (0.5 * acceleration.y * Δt * Δt);

velocity.x += acceleration.x * Δt;
velocity.y += acceleration.y * Δt;

(这基本上是物理101中的s = vt +½at²公式。)

施加速度

如果要在某个标准化方向上应用给定速度,则可以这样设置速度:

velocity.x = normalizedDirection.x * speed;
velocity.y = normalizedDirection.y * speed;

求速度

而且,如果您需要做相反的工作-从给定的速度向量得出速度和方向-您可以简单地使用勾股定理或.Length()方法:

speed = velocity.Length();

一旦知道了速度,就可以通过将速度除以速度来计算归一化方向(注意避免被零除):

if (speed != 0) {
    normalizedDirection.x = velocity.x / speed;
    normalizedDirection.y = velocity.y / speed;
} else {
    normalizedDirection.x = 0;
    normalizedDirection.y = 0;
}
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.