如何在精确的着陆位置坐标处停止精灵

How to stop a sprite at exact touchdown position coordinates

我想从屏幕的任意位置移动一个精灵(恰好是一个矩形),并让它恰好停在屏幕被触摸的位置。现在,我已经可以停止我的精灵了,但不能停在确切的触摸位置。在不牺牲准确性或冒着精灵根本不停止的风险的情况下,我找不到一个好的方法来做到这一点。

自然地 - 出现问题是因为当前位置是 Float,因此 Vector 永远不会(或极少)具有与触摸点(int)完全相同的坐标.

在下面的代码中,我通过简单地检查当前位置和目标位置(即触摸位置 Vector3)之间的距离来停止我的精灵,就像这样 if (touch.dst(currentPsition.x, currentPosition.y, 0) < 4)。 例如,如果精灵在位置 (5,5),我在 (100,100) 处触摸屏幕,它会停在 (98.5352,96.8283) 处。

我的问题是,如何将精灵停在准确的触摸位置,而不必近似?

void updateMotion() {
    if (moveT) {
        movement.set(velocity).scl(Gdx.graphics.getDeltaTime());
        this.setPosition(currentPosition.add(movement));
        if (touch.dst(currentPosition.x, currentPosition.y, 0) < 4)
            moveT = false;
    }
}

public void setMoveToTouchPosition(boolean moveT) {
    this.moveT = moveT;

    this.touch = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
    GameScreen.getCamera().unproject(touch);

    currentPosition = new Vector2(this.x, this.y);

    direction.set(new Vector2(touch.x, touch.y)).sub(currentPosition).nor();

    velocity = new Vector2(direction).scl(speed);
}

当然,由于很多原因,sprite 不能平滑地移动到触摸位置然后停在完全相同的位置。只需更改此

if (touch.dst(currentPosition.x, currentPosition.y, 0) < 4)
            moveT = false;

到这个

if (touch.dst(currentPosition.x, currentPosition.y, 0) < 2) {
            currentPosition.x = touch.x;
            currentPosition.y = touch.y;
            moveT = false;
}

一个快速但可接受的解决方案可能是使用 Rectangle class。考虑到您在移动实体周围制作了一个 Rectangle 并根据其当前位置不断更新其边界,它的纹理 width 和纹理 height。你可以在 overlaps 和 "target position" 时停止它。如果你这样做,你可以保证它会准确地停在那个位置。例如:

Texture entityTexture = new Texture("assets/image.png");

Rectangle entityBounds = new Rectangle();
entityBounds.set((currentPosition.x, currentPosition.y, entityTexture .getWidth(), entityTexture .getHeight()));

Rectangle targetBounds = new Rectangle();
targetBounds.set((targetPosition.x, targetPosition.y, 1, 1)); // make width and height 1 by 1 for max accuracy

public void update(){

  // update bounds based on new position

  entityBounds.set((currentPosition.x, currentPosition.y, entityTexture.getWidth(),   entityTexture.getHeight()));

  targetBounds.set((targetPosition.x, targetPosition.y, 1, 1));

  if(entityBounds.overlaps(targetBounds)){
    // do something
  }
}