哈勒2D Diagonal Movement的SFML游戏开发书



第4章中的《SFML游戏开发》一书给出了指导,即当你向两个方向(如右侧和顶部)增加速度时,移动速度将比向一个方向更快。

从研究中,我了解到观察到的行为是,你将在同一时期达到对角线距离,就像你向左或向右、向上或向下移动一样。这是错误的,因为对角线距离较长。

这本书通过除以2:的平方来纠正这个问题

sf::Vector2f velocity = mPlayerAircraft->getVelocity();
// If moving diagonally, reduce velocity (to have always same velocity)
if (velocity.x != 0.f && velocity.y != 0.f)
mPlayerAircraft->setVelocity(velocity / std::sqrt(2.f));

从额外的研究中,我发现可以通过将速度乘以速度的归一化向量来实现解。

velocity = mPlayerAircraft->getVelocity();
if (velocity.x != 0.f && velocity.y != 0.f) {
float velocityxsq = velocity.x * velocity.x;
float velocityysq = velocity.y * velocity.y;
float magnitude =  std::sqrt(velocityxsq + velocityysq);
sf::Vector2f normalizedVector = velocity / magnitude;
velocity.x = velocity.x * std::abs(normalizedVector.x);
velocity.y = velocity.y * std::abs(normalizedVector.y);
mPlayerAircraft->setVelocity(velocity);
}

两种实现的行为似乎都是正确的,但规范化值并不总是1/sqrt(2)。唯一一次计算是一样的是当游戏开始时,我开始做对角线运动。如果我向任何方向移动,然后进行对角线移动,则值会有所不同。

我做的规范化不正确吗?为什么这本书静态地使用sqrt(2)?

虽然我实际上拥有这本书,但我还没有时间读,所以下面只是一个逻辑假设

这本书只是假设速度矢量的方向分量总是-1、0或1。仅此而已。

确实,正确的解决方案是通过使用向量的长度(或大小)划分两个分量来规范化向量。

在本书的情况下,这是跳过的,所以为了简化,可以通过基本上使用编译时间常数sqrt(2.f)来删除整个计算。

最新更新