Haller 的 SFML 游戏开发书籍 2D Diagonal Movement

SFML Game Development Book by Haller 2D Diagonal Movement

Ch. 中的 SFML 游戏开发书籍4 给出的指导是,当您在两个方向(例如向右和向上)增加速度时,移动将比在一个方向上更快。

根据研究,我了解到观察到的行为是您将在同一时间到达对角线距离,就好像您向左或向右或向上或向下移动一样。这是错误的,因为对角线距离更长。

本书通过除以 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).

来删除整个计算