我正在做一个2D坦克炮塔游戏,你在屏幕中间旋转一个坦克,点击你的左按钮然后一个小弹丸移动到那个位置。
我目前处于当前位置和所需位置的位置,我现在需要做的是获得这两点的大小,这应该返回1或0。
这是我的C ++ VectorClass幅度函数:
float vector2D::magnitude(vector2D vec2)//<! Vector magnitude
{
float result;
result = (sqrt(x*vec2.x)+(y*vec2.y));
return result;
}
这是我将我想要的和当前位置标准化的代码:
currentPos.x = laserTexture.getSize().x/2.0f;
currentPos.y = laserTexture.getSize().y/2.0f;
desiredPos.x = sf::Mouse::getPosition().x;
desiredPos.y = sf::Mouse::getPosition().y;
normalisedLocation = magnitude(desiredPos - currentPos);
当前位置与我的laserTexture中间有关,这是屏幕中间的一个固定旋转点。
我想要的位置是鼠标点击,它返回X和Y中的位置(这有效)。
数学不是我的强项,所以当谈到编程这类东西时,我比其他人更挣扎,所以它花了我更长时间/我会想出一些不太优雅的解决方案。
我的最终目标是获得标准化位置,然后当点击鼠标左键时,坦克炮塔将会发射,并且射弹将移动到所需的位置。
所以澄清一下:
由于
答案 0 :(得分:5)
ad 1.)“我的幅度函数是否正确?”
不,您的maginutude()
方法几乎没有错误。你的:
result = (sqrt(x*vec2.x)+(y*vec2.y));
是
result = sqrt(x*vec2.x)+(y*vec2.y);
是
result = sqrt(x*vec2.x) + (y*vec2.y);
但你可能想写这个:
result = sqrt((x*vec2.x)+(y*vec2.y));
修改强>
我最初写道sqrt(x*vec2.x+y*vec2.y)
是正确的,但事实并非如此:
result = sqrt(vec2.x*vec2.x + vec2.y*vec2.y);
那是因为OP只想计算vec2的幅度,所以不需要使用this.x
和this.y
。出于这个原因,我建议将你的方法改为静态:
static float vector2D::magnitude(vector2D vec2)//<! Vector magnitude
{
return sqrt((vec2.x*vec2.x)+(vec2.y*vec2.y));
}
或仅使用实例值:
float vector2D::magnitude()//<! Vector magnitude
{
return sqrt((x*x)+(y*y));
}
在第二种情况下,您需要使用magnitude()
方法,如下所示:
(desiredPos - currentPos).magnitude();
补充说明:
desiredPos
和currentPos
之间的距离。(desiredPos - currentPos)
除以幅度值,您将获得标准化向量,即从currentPos
到desiredPos
的方向。desiredPos
和currentPos
相等,则幅度为零,无法对矢量进行标准化。normalisedLocation
变量。它的距离如上所述。广告2.)“我是否正确地规范了我想要的和当前的位置?”
我不确定如何理解这个问题,因为你没有规范化示例代码中的任何内容。无论如何,看看这个:
// This is from your code:
currentPos.x = laserTexture.getSize().x/2.0f;
currentPos.y = laserTexture.getSize().y/2.0f;
desiredPos.x = sf::Mouse::getPosition().x;
desiredPos.y = sf::Mouse::getPosition().y;
// Store direction to desired position. Currently length of this vector is
// distance between the two points.
vector2D dirToDesiredPos = (desiredPos - currentPos);
// Calculate distance between the two points.
float dirToDesiredPosDist = magnitude(desiredPos - currentPos);
// Detect whether the distance is zero. Problem is, you cannot compare float
// with zero (computer is not accurate enough) so we compare it with a delta
// value. It should be some small number, for example 0.01f.
// (Note that in this case we don't need to compare it with negative value -
// which would be -0.01f, because distance is always positive or zero.)
if(dirToDesiredPosDist < FLOAT_DELTA)
{
// User clicked on the tank, we cannot shoot!!!
}
else
{
// Following two lines do actuall normalization - direction of this vector
// is unchanged, but it's length is currently 1.
dirToDesiredPos.x /= dirToDesiredPosDist;
dirToDesiredPos.y /= dirToDesiredPosDist;
// Now dirToDesiredPos can be used to calculate to move your bullet to the
// desired location.
}
然而,仍有一个问题。它是以下几行:
currentPos.x = laserTexture.getSize().x/2.0f;
currentPos.y = laserTexture.getSize().y/2.0f;
这样,您可以计算激光纹理的中心,但只有在[0,0]位置渲染激光时,此位置才是正确的。否则你需要像这样更新它:
currentPos.x = laserTexture.getSize().x/2.0f + laserPos.x;
currentPos.y = laserTexture.getSize().y/2.0f + laserPos.y;
其中laserPos
是您的激光当前所在的位置。
答案 1 :(得分:1)
向量的范数是其坐标平方和的平方根。你的方法应该是:
float vector2D::magnitude(vector2D vec2)
{
return sqrt(vec2.x * vec2.x + vec2.y * vec2.y);
}
答案 2 :(得分:1)
矢量的大小,即其长度,将是
float vector2D::magnitude() const
{
return sqrt(x*x + y*y);
}
(它是具有边x和y的直角三角形的斜边。)
要对矢量进行标准化,即获得方向相同但长度为1的矢量,则将其坐标除以其幅度:
vector2D vector2D::normalise() const
{
float length = magnitude();
// Do something suitable to handle the case where the length is close to 0 here...
return vector2D(x / length, y / length);
}
,你的最后一行将是
normalisedDirection = (desiredPos - currentPos).normalise();
或更详细的
vector2D direction = desiredPos - currentPos;
normalisedDirection = location.normalise();
(我重命名了一个变量,以澄清我们正在计算方向,而不是位置。)
或者,您可以使用免费功能:
float magnitude(vector2D v)
{
return sqrt(v.x * v.x + v.y * v.y);
}
vector2D normalise(vector2D v)
{
float length = magnitude(v);
v.x /= length;
v.y /= length;
return v;
}
// ...
normalisedDirection = normalise(desiredPos - currentPos);
旁注:
你的函数中有一个拼写错误,使其更加错误:
(sqrt(x*vec2.x)+(y*vec2.y));
看起来很像
sqrt((x*vec2.x)+(y*vec2.y));
因为末尾有两个括号,但它实际上是
sqrt(x * vec2.x) + y * vec2.y;
为了避免这些问题,首先:不要害怕空格键,第二:不要使用过多的括号。
答案 3 :(得分:0)
为什么你需要幅度?你需要一个角度(度数或弧度)的方向。因为你已经拥有坦克的基本位置,以及你点击鼠标所需的位置,你需要计算它们与点的角度。你可以用一点点毕达哥拉斯和三角测量法找出角度,将你的坦克旋转到那个角度,然后在同一个航向上发射你的射弹。