LibGDX - 使用 InputProcessor 的多点触控处理
LibGDX - Multitouch handling using InputProcessor
一段时间以来,我一直在尝试在我的 android 游戏中设置适当的多点触控支持。对于输入处理,我使用我的 InputHandler(实现 InputProcessor)。我用这样的东西
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
screen.renderer.cam.unproject(touchPos);
if (left.isTouchDown((int) touchPos.x, (int) touchPos.y)) {
player.setMovingLeft(true);
player.leftPressed();
}
还有这个
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
screen.renderer.cam.unproject(touchPos);
if (left.isTouchUp((int) touchPos.x, (int) touchPos.y)) {
player.setMovingLeft(false);
player.leftReleased();
}
我已经设置了3个这样的按钮,但我不知道为什么它不起作用。我找到的所有答案在使用 InputProcessor 时都不是很有帮助。
我知道它与触摸指针和迭代输入有关,但不幸的是,我的知识到此为止。
代码 "when touched" 和 "when released" 确实有效,我使用键盘输入的方式相同。唯一的问题是多点触控。
您将 libGDX 输入轮询接口与 libGDX 输入事件 API 混合在一起。具体来说,这些调用:
Gdx.input.getX(), Gdx.input.getY()
相当于:
Gdx.input.getX(0), Gdx.input.getY(0)
参见 the getX documentation。所以你总是在读取第 0 个触摸索引的 x/y 坐标,与哪个触摸处于活动状态无关。
事件 API 即将过去 in the x, y and pointerID to the callback,因此您只需要执行以下操作:
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
Vector3 touchPos = new Vector3(screenX, screenY, 0);
screen.renderer.cam.unproject(touchPos);
if (left.isTouchDown((int) touchPos.x, (int) touchPos.y)) {
player.setMovingLeft(true);
player.leftPressed();
}
多点触控时需要使用"pointer"参数来区分手指
我遇到过一次类似的问题,试图在屏幕上设置3个按钮。这些按钮可以单独按下(这样就没问题了,你总是只用一根手指和一根指针 - 因此指针 ID 可以忽略),但它们也应该正确反应,如果按下其中任何两个,或者玩家按下所有按钮立刻。
您必须使用 InputProcessor 提供的指针 ID。指针 ID 是一个从 0 到 9 范围的整数(对于 10 个手指)。
我是这样做的:
首先为三个指针声明了三个变量:
int forwardPointer, leftPointer, rightPointer;
然后在 TouchDown 方法中我检查了哪个手指按下了哪个按钮(是第一次、第二次还是第三次按下?),并将此信息存储在我的变量中以备将来使用。
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if (game.forwardButton.contains(screenX, screenY)) {
game.forwardButton.isPressed=true;
forwardPointer=pointer;
}
if (game.leftButton.contains(screenX, screenY)) {
game.leftButton.isPressed=true;
leftPointer=pointer;
}
if (game.rightButton.contains(screenX, screenY)) {
game.rightButton.isPressed=true;
rightPointer=pointer;
}}
然后,在 TouchUp 方法中,我检查了哪个手指被抬起(通过比较来自 TouchUp 方法的指针 ID 与存储的指针变量值),并据此,我 "relased" 正确的按钮。
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
if (pointer==forwardPointer) {
game.forwardButton.isPressed=false;
}
if (pointer==leftPointer) {
game.leftButton.isPressed=false;
}
if (pointer==rightPointer) {
game.rightButton.isPressed=false;
}}
这对我有用。无需使用 Gdx.input.getX()、Gdx.input.getY(),因为
这些值已经由 touchDown 和 touchUp 方法(screenX 和 screenY)给出。
由于在事件方法中传递的指针值是触摸手指的唯一 ID,您可以使用散列图来存储和操作具有该唯一键的所有触摸。
创建哈希图。
public static HashMap<Integer, Vector2> touchlist;
public Constructor(){
touchlist=new HashMap<>();
}
如果触摸不存在,则添加为新的。
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if(!touchlist.containsKey(pointer))touchlist.put(pointer, new Vector2(screenX, screenY));
return false;
}
如果手指向上,则移除。
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
touchlist.remove(pointer);
return false;
}
如果手指被拖动,更新相应的触摸事件
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
Vector2 touch=touchlist.get(pointer);
if(touch!=null)touch.set(screenX, screenY);
return false;
}
键是指针,值是将存储触摸坐标的向量。
要在任何地方使用它们,只需遍历地图
for(Integer key:touchlist.keySet()){
Vector2 touchpos=touchlist.get(key);
//do your manipulation here
if(isvalid(touchpos)) //use if valid skip if not etc..
}
一段时间以来,我一直在尝试在我的 android 游戏中设置适当的多点触控支持。对于输入处理,我使用我的 InputHandler(实现 InputProcessor)。我用这样的东西
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
screen.renderer.cam.unproject(touchPos);
if (left.isTouchDown((int) touchPos.x, (int) touchPos.y)) {
player.setMovingLeft(true);
player.leftPressed();
}
还有这个
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
screen.renderer.cam.unproject(touchPos);
if (left.isTouchUp((int) touchPos.x, (int) touchPos.y)) {
player.setMovingLeft(false);
player.leftReleased();
}
我已经设置了3个这样的按钮,但我不知道为什么它不起作用。我找到的所有答案在使用 InputProcessor 时都不是很有帮助。
我知道它与触摸指针和迭代输入有关,但不幸的是,我的知识到此为止。
代码 "when touched" 和 "when released" 确实有效,我使用键盘输入的方式相同。唯一的问题是多点触控。
您将 libGDX 输入轮询接口与 libGDX 输入事件 API 混合在一起。具体来说,这些调用:
Gdx.input.getX(), Gdx.input.getY()
相当于:
Gdx.input.getX(0), Gdx.input.getY(0)
参见 the getX documentation。所以你总是在读取第 0 个触摸索引的 x/y 坐标,与哪个触摸处于活动状态无关。
事件 API 即将过去 in the x, y and pointerID to the callback,因此您只需要执行以下操作:
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
Vector3 touchPos = new Vector3(screenX, screenY, 0);
screen.renderer.cam.unproject(touchPos);
if (left.isTouchDown((int) touchPos.x, (int) touchPos.y)) {
player.setMovingLeft(true);
player.leftPressed();
}
多点触控时需要使用"pointer"参数来区分手指
我遇到过一次类似的问题,试图在屏幕上设置3个按钮。这些按钮可以单独按下(这样就没问题了,你总是只用一根手指和一根指针 - 因此指针 ID 可以忽略),但它们也应该正确反应,如果按下其中任何两个,或者玩家按下所有按钮立刻。 您必须使用 InputProcessor 提供的指针 ID。指针 ID 是一个从 0 到 9 范围的整数(对于 10 个手指)。 我是这样做的:
首先为三个指针声明了三个变量:
int forwardPointer, leftPointer, rightPointer;
然后在 TouchDown 方法中我检查了哪个手指按下了哪个按钮(是第一次、第二次还是第三次按下?),并将此信息存储在我的变量中以备将来使用。
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if (game.forwardButton.contains(screenX, screenY)) {
game.forwardButton.isPressed=true;
forwardPointer=pointer;
}
if (game.leftButton.contains(screenX, screenY)) {
game.leftButton.isPressed=true;
leftPointer=pointer;
}
if (game.rightButton.contains(screenX, screenY)) {
game.rightButton.isPressed=true;
rightPointer=pointer;
}}
然后,在 TouchUp 方法中,我检查了哪个手指被抬起(通过比较来自 TouchUp 方法的指针 ID 与存储的指针变量值),并据此,我 "relased" 正确的按钮。
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
if (pointer==forwardPointer) {
game.forwardButton.isPressed=false;
}
if (pointer==leftPointer) {
game.leftButton.isPressed=false;
}
if (pointer==rightPointer) {
game.rightButton.isPressed=false;
}}
这对我有用。无需使用 Gdx.input.getX()、Gdx.input.getY(),因为 这些值已经由 touchDown 和 touchUp 方法(screenX 和 screenY)给出。
由于在事件方法中传递的指针值是触摸手指的唯一 ID,您可以使用散列图来存储和操作具有该唯一键的所有触摸。
创建哈希图。
public static HashMap<Integer, Vector2> touchlist;
public Constructor(){
touchlist=new HashMap<>();
}
如果触摸不存在,则添加为新的。
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if(!touchlist.containsKey(pointer))touchlist.put(pointer, new Vector2(screenX, screenY));
return false;
}
如果手指向上,则移除。
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
touchlist.remove(pointer);
return false;
}
如果手指被拖动,更新相应的触摸事件
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
Vector2 touch=touchlist.get(pointer);
if(touch!=null)touch.set(screenX, screenY);
return false;
}
键是指针,值是将存储触摸坐标的向量。 要在任何地方使用它们,只需遍历地图
for(Integer key:touchlist.keySet()){
Vector2 touchpos=touchlist.get(key);
//do your manipulation here
if(isvalid(touchpos)) //use if valid skip if not etc..
}