使用输入处理器使对象跟随触摸输入的 x 轴,对象变得疯狂

Using inputprocessor so an object follows the x-axis of the touch-input, object goes crazy

所以我想要这样当用户触摸屏幕时,对象跟随 touchpos 的 x 轴。当我通过轮询 (Gdx.input.getX()) 执行此操作时,它的工作方式就像它必须的那样。但是对于输入处理器,当触摸屏幕时,对象会在整个屏幕上疯狂。我真的不明白为什么。这是代码

Player.java :

public class Player extends Entity
{
    MyInputProcessor input;

    public Player(float x, float y, Sprite sprite)
    {
        super(x, y, sprite);
        input = new MyInputProcessor();
        Gdx.input.setInputProcessor(input);
    }

    public void update(final Application app)
    {
        handleInput(app);
        super.update();
    }

    public void handleInput(Application app)
    {
        if (input.touchDown)
        {
            Vector2 touchPos = app.viewport.unproject(input.screenTouchPos);
            position.x = touchPos.x - sprite.getWidth() / 2;
        }
    }
}

MyInputProcessor.java :

public class MyInputProcessor implements InputProcessor
{
    public boolean touchDown = false;
    public Vector2 screenTouchPos;

    public MyInputProcessor()
    {
        screenTouchPos = new Vector2();
    }

    @Override
    public boolean keyDown(int keycode)
    {
        return false;
    }

    @Override
    public boolean keyUp(int keycode)
    {
        return false;
    }

    @Override
    public boolean keyTyped(char character)
    {
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button)
    {
        touchDown = true;
        screenTouchPos.set(screenX, screenY);
        return false;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button)
    {
        touchDown = false;
        return false;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer)
    {
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY)
    {
        return false;
    }

    @Override
    public boolean scrolled(int amount)
    {
        return false;
    }
}

这一行

Vector2 touchPos = app.viewport.unproject(input.screenTouchPos);

不为您提供未投影矢量的副本。它正在修改输入 Vector2 并将相同的引用返回给您。由于您的输入处理器仅在您按下时重置其 Vector2,因此只要您按住手指,您的 Player class 就会在每一帧上取消投影相同的向量。在同一向量上多次调用 unproject 显然会开始产生垃圾结果。

因此,请将您自己的额外 Vector 2 放在手边。

private final Vector2 unprojectedTouchPos = new Vector2();

然后在每一帧上将触摸位置向量复制到此向量中并使用此向量:

public void handleInput(Application app)
{
    if (input.touchDown)
    {
        unprojectedTouchPos.set(input.screenTouchPos);
        app.viewport.unproject(unprojectedTouchPos);
        position.x = unprojectedTouchPos.x - sprite.getWidth() / 2;
    }
}

编辑: 根据您的评论,您还希望随着手指的拖动实时更新位置,因此将其添加到 InputProcessor 的 touchDragged 方法中:

screenTouchPos.set(screenX, screenY);