使用输入处理器使对象跟随触摸输入的 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);
所以我想要这样当用户触摸屏幕时,对象跟随 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);