我是游戏开发的新手,我遇到了问题。
我想知道每秒的新玩家位置,这里有一个例子:
玩家从(2.5; 2.5)开始,然后进入(6.5; 3.8)。
他的速度是每秒2个单位的速度,我想知道1秒后的玩家位置。所以像这样:
我想知道它每秒都是A但我根本不知道我怎么能这样做...... 我希望你能提前帮助我!
答案 0 :(得分:3)
首先,您需要计算出所覆盖的总距离,这是您的向量。矢量是一个运动,而不是空间中的两个点。
然后你只需将每个维度x和y除以这种情况下的时间,即以测量单位(秒)为单位进行移动以获得每秒的距离。
然后将每个x和y乘以0的秒数,即示例中的1秒,以便在1秒后得到位置。
我不知道您的框架或库中有什么可用,但是一个好的Vector
类将非常有用,您将希望能够直接对矢量实例进行数学运算,例如:
Point origin = sprite.Position; // Assumes some sprite object with a position.
Point dest = new Point(200,344); // Destination.
Vector totalTranslation = new Vector(dest.X - origin.X, dest.Y - origin.Y);
Vector perSecond = totalTranslation / 60; // assuming takes a minute to move.
Vector distanceMoved = perSecond * 4; // distance moved after 4 seconds.
Point newPosition = new Point(origin.X + distanceMoved.X, origin.Y + distanceMoved.Y);
sprite.Position = newPosition; // Or using some orchestration class...
spriteManager.Move(sprite, newPosition); // ...like this.
注意能够直接划分矢量。否则,你必须划分向量的每个空间维度并创建一个新的向量,或者做一个辅助类来做它。
在现实生活中,您可能希望基于毫秒计算。我不会使用固定的帧计数器,因为它可能看起来很讨厌,但是根据计时器完成所有工作。
正如我所说,一个好的库或不可变的Vector结构/类是这里的关键。然后是一个在方格纸上思考问题的案例。
此外,建立一个小功能的调色板,你可以链在一起做更酷,更大的东西。
另一个有趣的问题是使用缓动函数在给定时间之后计算坐标,以实现精灵在“落地”时减速的效果。
答案 1 :(得分:3)
他的速度是每秒2个单位。
我认为,'单位'的意思是'长度为1的矢量'。
首先,您需要计算AB矢量(运动矢量):
mov_vec = [xb-xa, yb-ya] = [6.5 - 2.5, 3.8 - 2.5] = [4, 1.3]
所以,我们知道,总单位的运动是[4,1.3]。我们需要规范化这个向量。归一化向量(单位向量)'norm_mov_vec'将与'mov_vec'成为同向,但它的长度为1.如果你想知道更多邻接单位向量,请参见this link。
计算运动矢量的长度:
mov_vec_len = sqrt( 4^2 + 1.3^2 ) ~= 4.2059
计算标准化向量:
norm_mov_vec = [4/4.2059, 1.3/4.2059] ~= [0.9510, 0.3090]
就是这样。 'norm_mov_vec'是你的'单位运动矢量',所以如果玩家以每秒N个单位的速度向那个方向移动,你可以很容易地计算它在T秒后的位置:
pos_after_T_sec_with_speed_N_units_per_sec = start_pos +(N * T * norm_mov_vec)
编辑: 示例代码,使用XNA中的Vector2类型。无法测试,但我希望你能得到这个想法:
//In your case:
//start_pos = 'A' point
//end_pos = 'B' point
//time = number of seconds that elapsed
//speed = number of units per second
Vector2 calculatePosition(ref Vector2 start_pos, ref Vector2 end_pos, Uint32 time, Uint32 speed)
{
Vector2 mov_vec = Vector2.Substract(end_pos, start_pos);
Vector2 norm_mov_vec = Vector2.Normalize(mov_vec);
Vector2 delta_vec = norm_mov_vec * time * speed;
return Vector2.Add(start_pos, delta_vec);
}
答案 2 :(得分:2)
这不是编程,而是矢量数学,但无论如何:
您的播放器正在沿着矢量BA(B点减去A点)移动,这是
Direction Vector: ( 4.0 / 1.3 )
此向量的长度为:
SquareRoot(4.0 * 4.0 + 1.3 * 1.3) = 4.2
相同方向的矢量和长度的一个单位因此是两个分量除以长度4.2的矢量:
Direction Vector of length 1: (0.95 / 0.30)
由于你的玩家很快并且移动了两个单位,所以它将是双倍长度:
Direction Vector of length 2: (1.90 / 0.60)
现在每个勾选,分别为玩家坐标添加1.90和0.60,直到它们等于(大致)目标坐标。
答案 3 :(得分:0)
x-位移:6.5-2.5 = 4
y-位移:3.8-2.5 = 1.3
Math.sqrt((4n)(4n)+(1.3n)(1.3n))= 2
N = 2 / Math.sqrt(17.69)
x-displacement / second = 4n = 8 / Math.sqrt(17.69)= 1.90207
y-displacement / second = 1.3n = 2.6 / Math.sqrt(17.69)= 0.61817
所以在得到这些值之后,每秒计算位置真的很容易
答案 4 :(得分:0)
您可以使用(作为通用解决方案)这些简单的三角公式:
x = A.x + v * cos(fi) * t;
y = B.y + v * sin(fi) * t;
fi = atan2(B.y - A.y, B.x - A.x);
样本解决方案
// Since there's no common 2d Point double based type,
// let (x, y) point be represented as Tuple<Double, Double>
// where Item1 is x, and Item2 is y
public static Tuple<Double, Double> Move(Tuple<Double, Double> fromPoint,
Tuple<Double, Double> toPoint,
Double velocity,
Double time) {
Double fi = Math.Atan2(toPoint.Item2 - fromPoint.Item2, toPoint.Item1 - fromPoint.Item1);
return new Tuple<Double, Double>(
fromPoint.Item1 + velocity * Math.Cos(fi) * time,
fromPoint.Item2 + velocity * Math.Sin(fi) * time);
}
...
for (int t = 0; t < 10; ++t) {
Tuple<Double, Double> position =
Move(new Tuple<Double, Double>(2.5, 2.5),
new Tuple<Double, Double>(6.5, 3.8),
2.0,
t);
Console.Write("t = ");
Console.Write(t);
Console.Write(" x = ");
Console.Write(position.Item1);
Console.Write(" y = ");
Console.Write(position.Item2);
Console.WriteLine();
}