为移动的物体指明方向
Giving a direction to a moving object
我想用SDL制作一款塔防游戏。在开始这个项目之前,我会试验在编写游戏时需要做的所有事情。在我目前正在做的测试中,有一个塔(静态物体),在其范围内的目标(移动物体),以及从炮塔向目标发射的射击(移动物体)。 我没能做到的是找到一种方法给 'shoot' 物体一个方向。射击对象是指当目标在射程内时塔发射的对象。此外,无论方向是什么,射击都应始终具有相同的速度,这禁止使用公式 dirx = x2 - x1
.
芽是定义如下的结构:
typedef struct shoot
{
SDL_Surface *img; // Visual representation of the shoot object.
SDL_Rect pos; // Position of the object, it's a structure containing
// coordinates x and y (these are of type int).
int index;
float dirx; // dirx and diry are the movement done by the shoots object in
// 1 frame, so that for each frame, the object shoot is moved dirx
// pixels on the axis x and diry pixels on the axis y
float diry; // (the program deals with the fact that the movement will be done
// with integers and not with floats, that is no problem to me)
float posx; // posx and posy are the real, precise coordinates of the shoot
float posy;
struct shoot *prev;
struct shoot *next;
} shoot;
我需要的是在给定当前帧中的位置和方向的情况下计算下一帧中拍摄对象的位置的方法。
这是我能找到的最好的(请注意,这是纸上写的公式,所以名称是简化的,与代码中的名称不同):
dirx = d * ((p2x - p1x) / ((p2x - p1x) + (p2y - p1y)))
diry = d * ((p2y - p1y) / ((p2x - p1x) + (p2y - p1y)))
dirx
和 diry
对应于一帧内在 x 轴和 y 轴上拍摄所完成的运动,以像素为单位。
d
是乘数,大括号(所有不是 d
的部分)是系数。
p2
是射击的瞄准点(瞄准的目标中心)。 p1
为拍摄对象的当前位置。 x
或y
表示我们使用点的坐标x或y。
这个公式的问题是它给了我一个不精确的值。例如,沿对角线瞄准会使射击速度比直接向北瞄准慢。而且,它没有朝着正确的方向发展,我找不到为什么,因为我的论文测试表明我是对的...
我希望在这里得到一些帮助,以找到使拍摄正确移动的公式。
如果 p1
是 shoot
对象的来源,p2
是目的地,s
是您希望移动它的速度(每单位帧或每秒 - 后者更好),则对象的 速度 由
给出
float dx = p2.x - p1.x, dy = p2.y - p1.y,
inv = s / sqrt(dx * dx + dy * dy);
velx = inv * dx; vely = inv * dy;
(您可能应该将 dir
更改为 vel
,因为它是一个更合理的变量名称)
您的尝试似乎是通过 曼哈顿距离 对方向向量进行归一化,这是错误的 - 您必须通过 欧几里得距离 进行归一化,这是由 sqrt
项给出的。
我想用SDL制作一款塔防游戏。在开始这个项目之前,我会试验在编写游戏时需要做的所有事情。在我目前正在做的测试中,有一个塔(静态物体),在其范围内的目标(移动物体),以及从炮塔向目标发射的射击(移动物体)。 我没能做到的是找到一种方法给 'shoot' 物体一个方向。射击对象是指当目标在射程内时塔发射的对象。此外,无论方向是什么,射击都应始终具有相同的速度,这禁止使用公式 dirx = x2 - x1
.
芽是定义如下的结构:
typedef struct shoot
{
SDL_Surface *img; // Visual representation of the shoot object.
SDL_Rect pos; // Position of the object, it's a structure containing
// coordinates x and y (these are of type int).
int index;
float dirx; // dirx and diry are the movement done by the shoots object in
// 1 frame, so that for each frame, the object shoot is moved dirx
// pixels on the axis x and diry pixels on the axis y
float diry; // (the program deals with the fact that the movement will be done
// with integers and not with floats, that is no problem to me)
float posx; // posx and posy are the real, precise coordinates of the shoot
float posy;
struct shoot *prev;
struct shoot *next;
} shoot;
我需要的是在给定当前帧中的位置和方向的情况下计算下一帧中拍摄对象的位置的方法。
这是我能找到的最好的(请注意,这是纸上写的公式,所以名称是简化的,与代码中的名称不同):
dirx = d * ((p2x - p1x) / ((p2x - p1x) + (p2y - p1y)))
diry = d * ((p2y - p1y) / ((p2x - p1x) + (p2y - p1y)))
dirx
和diry
对应于一帧内在 x 轴和 y 轴上拍摄所完成的运动,以像素为单位。d
是乘数,大括号(所有不是d
的部分)是系数。p2
是射击的瞄准点(瞄准的目标中心)。p1
为拍摄对象的当前位置。x
或y
表示我们使用点的坐标x或y。
这个公式的问题是它给了我一个不精确的值。例如,沿对角线瞄准会使射击速度比直接向北瞄准慢。而且,它没有朝着正确的方向发展,我找不到为什么,因为我的论文测试表明我是对的...
我希望在这里得到一些帮助,以找到使拍摄正确移动的公式。
如果 p1
是 shoot
对象的来源,p2
是目的地,s
是您希望移动它的速度(每单位帧或每秒 - 后者更好),则对象的 速度 由
float dx = p2.x - p1.x, dy = p2.y - p1.y,
inv = s / sqrt(dx * dx + dy * dy);
velx = inv * dx; vely = inv * dy;
(您可能应该将 dir
更改为 vel
,因为它是一个更合理的变量名称)
您的尝试似乎是通过 曼哈顿距离 对方向向量进行归一化,这是错误的 - 您必须通过 欧几里得距离 进行归一化,这是由 sqrt
项给出的。