简体   繁体   English

LibGDX-使用InputProcessor进行多点触控

[英]LibGDX - Multitouch handling using InputProcessor

I am trying to set up proper multitouch support in my android game for some time. 我试图在我的Android游戏中设置适当的多点触控支持一段时间。 For input handling I use my InputHandler(implementing InputProcessor). 对于输入处理,我使用我的InputHandler(实现InputProcessor)。 I use something like this 我用这样的东西

    @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();
    }

and this 和这个

    @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();
    }

I have set up 3 buttons like that, but I have no idea why it doesn't work. 我已经设置了3个这样的按钮,但是我不知道为什么它不起作用。 All the answers I've found aren't very helpful when using InputProcessor. 使用InputProcessor时,我发现的所有答案都不太有用。

I know that it has something to do with touch pointers and iterating input, but that's where my knowledge ends, unfortunately. 我知道它与触摸指针和迭代输入有关,但是不幸的是,这就是我所学的知识的终点。

The code "when touched" and "when released" is working for sure, I'm using it the same way with keyboard input. 确保代码“触摸时”和“释放时”可以正常工作,我在键盘输入中使用的方式相同。 The only problem is multitouch. 唯一的问题是多点触控。

I encoutered similar problem once,trying to set up 3 buttons on screen. 我曾经遇到过类似的问题,试图在屏幕上设置3个按钮。 Those buttons can be pressed separately (then there is no problem, you always use just one finger and one pointer - therefore pointer ID can be ignored), but they should also react properly, if any two of them are pressed, or player presses all at once. 可以分别按下这些按钮(这样就没问题,您总是只用一根手指和一根指针-因此可以忽略指针ID),但是如果按下了其中两个按钮,或者玩家按下了所有按钮,它们也应该做出正确的反应立刻。 You have to make use of pointer ID, given by InputProcessor. 您必须使用InputProcessor提供的指针ID。 Pointer ID is an int from 0 to 9 range (for 10 fingers). 指针ID是一个介于0到9范围之间的整数(用于10个手指)。 I did it that way: 我是这样做的:

first declared three variables for three pointers: 首先为三个指针声明三个变量:

int forwardPointer, leftPointer, rightPointer;

then in TouchDown method i checked, which finger pressed which button (was it first, second or third press?), and stored this information in my variables for future use. 然后在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;
    }}

and then, in TouchUp method i checked, which finger was lifted up (by comparing pointer ID from TouchUp method with stored pointer variable value), and according to this, i "relased" proper button. 然后,在TouchUp方法中,我检查了哪只手指被抬起(通过将TouchUp方法中的指针ID与存储的指针变量值进行比较),并据此“释放”了正确的按钮。

    @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;
    }}

This worked for me. 这对我有用。 No need to use Gdx.input.getX(), Gdx.input.getY(), as those values are already given by touchDown and touchUp method (screenX and screenY). 无需使用Gdx.input.getX(),Gdx.input.getY(),因为这些值已经由touchDown和touchUp方法(screenX和screenY)给出。

You're mixing the libGDX input polling interfaces with the libGDX input event API. 您正在将libGDX输入轮询接口与libGDX输入事件API混合使用。 Specifically, these calls: 具体来说,这些调用:

 Gdx.input.getX(), Gdx.input.getY()

are equivalent to: 等效于:

 Gdx.input.getX(0), Gdx.input.getY(0)

see the getX documentation . 请参阅getX文档 So you're always reading the x/y coordinates of the 0th touch index, independent of which touch is active. 因此,您始终在读取第0个触摸索引的x / y坐标,而与激活哪个触摸无关。

The event API is passing in the x, y and pointerID to the callback , so you just need to do something like: 事件API 会将x,y和pointerID传递给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();
}

You should use the "pointer" parameter to distinguish fingers during multi-touch. 您应使用“指针”参数在多点触摸过程中区分手指。

Since pointer value passed in event methods is a unique id of the touching finger, you can use a hashmap to store and manipulate all of the touches with that unique key. 由于在事件方法中传递的指针值是触摸手指的唯一ID,因此您可以使用哈希映射来存储和操纵具有该唯一键的所有触摸。

Create a hashmap. 创建一个哈希图。

public static HashMap<Integer, Vector2> touchlist;
public Constructor(){
    touchlist=new HashMap<>();
}

Add as new if touch is not present. 如果没有触摸,则添加为新的。

@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;
}

Remove if finger is up. 如果手指朝上,请取下。

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    touchlist.remove(pointer);
    return false;
}

Update the corresponding touch event if finger is dragged 如果拖动手指,则更新相应的触摸事件

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    Vector2 touch=touchlist.get(pointer);
    if(touch!=null)touch.set(screenX, screenY);
    return false;
}

Key is the pointer and value is a vector that will store the touch coordinates. 键是指针,值是将存储触摸坐标的向量。 And to use them anywhere you want just iterate over the map 并在您想要遍历地图的任何地方使用它们

for(Integer key:touchlist.keySet()){
    Vector2 touchpos=touchlist.get(key);
    //do your manipulation here
    if(isvalid(touchpos)) //use if valid skip if not etc..
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM