2

代码:

我有一个功能如下:

bool Action::approach (img_comp &mover, sf::Vector2f start, sf::Vector2f end, int speed)
{
    //Get the change in x and y
    float delta_x = (end.x - start.x) / speed;
    float delta_y = (end.y - start.y) / speed;

    //Move the sprite
    mover.sprite.move(delta_x, delta_y);

    //Check if the sprite has met the end
    if (mover.sprite.getPosition() == end)
        return true;

    return false;
}

(其中sf::Vector2f基本上是一个带有xy浮点参数的结构,例如 xy 网格上的一个点)

问题:

不出所料,由于float. 在这种情况下,我使用什么算法让我的精灵准确地落在end点上,而不管四舍五入?

注意:宽容不是我问题的答案。这只是一种妥协。我想要第一次完美选择点的算法,不管任何舍入。如果这是不可能的,请告诉我。

4

3 回答 3

2

您的精灵可以向左或向右,因此您应该考虑使用当前位置和终点之间的绝对差。

Epsilon = 1e-9

deltaX = (end.x - start.x) / speed
deltaY = (end.y - start.y) / speed

dirX = Math.sgn(deltaX)
dirY = Math.sgn(deltaY)

mover.sprite.move(deltaX, deltaY);

crossedEndX = dirX * (mover.sprite.getPosition().x - end.x) > Epsilon
crossedEndY = dirY * (mover.sprite.getPosition().y - end.y) > Epsilon

if(crossedEndX && crossedEndY)
  return true
于 2013-07-28T09:02:36.663 回答
2

我想你已经有了答案,因为float你不应该做四舍五入,mover.sprite.getPosition() == end而是看看是否mover.sprite.getPosition() - end小于某个数字,让我们说

 float diff = mover.sprite.getPosition() - end;

 if (diff < 0)
    diff *= -1;

 //Check if the sprite has met the end
 if (diff > 0.01)
        return true;

这样你就不会检查你是否在现场,而是检查你是否离现场足够近。为了改善这一点,您还可以这样做:

 float diff = mover.sprite.getPosition() - end;

 if (diff < 0)
    diff *= -1;

 //Check if the sprite has met the end
 if (diff > 0.01){
        mover.sprite.getPosition() = end; //this might not be the exact syntax but the idea is clear i hope
        return true;
 }
于 2013-07-28T08:49:51.490 回答
2

代替直接比较,您可以执行类似“如果点接近结束则点 = 结束”之类的操作

/* Set TOLERANCE to whatever makes sense.
 * Could have different X and Y values too...
 */
#define TOLERANCE 0.01
sf::Vector2f &newPos = mover.sprite.getPoition();
if (abs(newPos[0] - end[0]) < TOLERANCE &&
    abs(newPos[1] - end[1]) < TOLERANCE) {
{
    mover.sprite.setPosition(end);
    result = true;
}
于 2013-07-28T08:51:07.340 回答