Search code examples
javaandroidlibgdx

Java LibGDX Multi Touch Movement


What is the problem? I am using this code to movement for two players. But it is not working. Player1 is more quick than player2. How can I fix?

for (byte i = 0; i < 20; i++) {maxDistance = 10 * Gdx.graphics.getDeltaTi

me();
                if (Gdx.input.isTouched(i) && Gdx.input.getY()<= 400) {
                    player1TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
                    camera.unproject(player1TouchPosition);
                }
                player1Tmp.set(player1TouchPosition.x, player1TouchPosition.y).sub(player1Rectangle.x, player1Rectangle.y);
                if (player1Tmp.len() <= maxDistance) {
                    player1Rectangle.x = player1TouchPosition.x;
                    player1Rectangle.y = player1TouchPosition.y;
                } else {
                    player1Tmp.nor().scl(maxDistance);
                    player1Rectangle.x += player1Tmp.x;
                    player1Rectangle.y += player1Tmp.y;
                }
                if (Gdx.input.isTouched(i) && Gdx.input.getY() >= 401) {
                    player2TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
                    camera.unproject(player2TouchPosition);
                }
                player2Tmp.set(player2TouchPosition.x, player2TouchPosition.y).sub(player2Rectangle.x, player2Rectangle.y);
                if (player2Tmp.len() <= maxDistance) {
                    player2Rectangle.x = player2TouchPosition.x;
                    player2Rectangle.y = player2TouchPosition.y;
                } else {
                    player2Tmp.nor().scl(maxDistance);
                    player2Rectangle.x += player2Tmp.x;
                    player2Rectangle.y += player2Tmp.y;
                }
            }

Solution

  • Two errors jump out at me:

    1. You used getY() instead of getY(i) in a couple of places, so the criteria are mixed up for any pointer besides the most recent one.

    2. You wrapped it all in a loop that runs 20 times, so you are moving each player 20 times a frame instead of one time each, at most. The movement should be applied outside the loop.

    This problem is more complicated than it initially looks, because you have to deal with rejecting extra fingers on either side of the screen. Suppose pointer 1 is a finger on the top half of the screen. If pointer 2 is a finger on the top half, you want to reject it, but if it's on the bottom half, you want to use it to move player 2. If pointers 1 and 2 are both on the top, you want to accept pointer 3 only if it's on the bottom but you want to always reject it if pointers 1 and 2 are on opposite sides.

    Furthermore, if only one finger is down, but it slides across the boundary to the other side, you want to be sure you don't let it start controlling the opposite player.

    Here's one possible strategy. Track the first pointer down on each side and reset it whenever the tracked pointer is released. Only update target positions for the two currently tracked pointers.

    private int player1Pointer = -1, player2Pointer = -1;
    
    // render():    
    
    //stop tracking released fingers
    if (player1Pointer >=0 && !Gdx.input.isTouched(player1Pointer))
        player1Pointer = -1;
    if (player2Pointer >=0 && !Gdx.input.isTouched(player2Pointer))
        player2Pointer = -1;
    
    //check for new pointers and update target positions
    for (int i = 0; i<20; i++){
        if (!Gdx.input.isTouched(i))
            continue;
        if (Gdx.input.getY(i) <= 400){ //bottom, player 1
            if (player2Pointer == i)
                continue; //player 2 slid finger across boundary, ignore it
            if (player1Pointer < 0)
                player1Pointer = i; //first finger down on this side of screen, track it
            if (player1Pointer == i){ //this is the tracked finger, update target
                player1TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
                camera.unproject(player1TouchPosition);
            }
        } else { //top, player 2
            if (player1Pointer == i)
                continue;
            if (player2Pointer < 0)
                player2Pointer = i;
            if (player2Pointer == i){
                player2TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
                camera.unproject(player2TouchPosition);
            }
        }
    }
    
    //update movement toward targets
    maxDistance = 10 * Gdx.graphics.getDeltaTime();
    temp.set(player1TouchPosition.x, player1TouchPosition.y).sub(player1Rectangle.x, player1Rectangle.y);
    if (temp.len() <= maxDistance) {
        player1Rectangle.x = player1TouchPosition.x;
        player1Rectangle.y = player1TouchPosition.y;
    } else {
        temp.nor().scl(maxDistance);
        player1Rectangle.x += temp.x;
        player1Rectangle.y += temp.y;
    }
    temp.set(player2TouchPosition.x, player2TouchPosition.y).sub(player2Rectangle.x, player2Rectangle.y);
    if (temp.len() <= maxDistance) {
        player2Rectangle.x = player2TouchPosition.x;
        player2Rectangle.y = player2TouchPosition.y;
    } else {
        temp.nor().scl(maxDistance);
        player2Rectangle.x += temp.x;
        player2Rectangle.y += temp.y;
    }