-1
\$\begingroup\$

In my libGDX game I have finally managed to get the sprite to move the way I want him to but for some reason my desired outcome only works the first time I run the code. If I try to run it again, he immediately flies off the screen. If I then comment out one of the brackets, save and then put it back in and run a test, he moves as I want him to (but only the first time). Am I missing something?

EDIT: Ok I changed the code and now I have a new problem, he moves but not smoothly like he does when I move him with the keyboard. now he sort of teleports forwards or backwards about 5pixels every time the screen is clicked (or touched).

Partial Player class:

public class Player extends Entity implements InputProcessor{

OrthographicCamera camera;
Rectangle rectangle;
Vector3 touchPos;

public Player(Vector2 pos, Vector2 direction) {
    super(TextureManager.PLAYER, pos, direction);
    rectangle = new Rectangle(); //for hitbox
    }

@Override
public void update() {

    camera = new OrthographicCamera(240, 400);
    camera.position.set(240 / 2, 400 / 2, 0);
    rectangle.set(pos.x, pos.y + 40, 32, 22); //hitbox
    touchPos = new Vector3();

    pos.add(direction);{

        Gdx.input.setInputProcessor(this);


    //the keyboard inputs below work exactly how I want them to     
    if(Gdx.input.isKeyPressed(Keys.A)) // left
        setDirection(-300, 0);
    else if(Gdx.input.isKeyPressed(Keys.D)) // right
        setDirection(300, 0);
    else
        setDirection(0, 0);         
    }

    // make sure player stays inside stage
    if (pos.x < 0) pos.x = 0;
    else if (pos.x > 240 - 32) pos.x = 240 - 32;

}

public void moveLeft() {
    setDirection(-300, 0);
}

public void moveRight() {
    setDirection(300, 0);
}

public void Still() {
    setDirection(0, 0);
}


@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    // TODO Auto-generated method stub
    if (screenX < ManicMeltdowns.WIDTH / 2 && screenY > ManicMeltdowns.HEIGHT / 2){
        moveLeft();
    }

    if (screenX > ManicMeltdowns.WIDTH / 2 && screenY > ManicMeltdowns.HEIGHT / 2){
        moveRight();
    }
    return true;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    // TODO Auto-generated method stub
    if (screenX < ManicMeltdowns.WIDTH / 2 && screenY > ManicMeltdowns.HEIGHT / 2){
        Still();
    }

    if (screenX > ManicMeltdowns.WIDTH / 2 && screenY > ManicMeltdowns.HEIGHT / 2){
        Still();
    }
    return true;
}

Thanks

\$\endgroup\$
4
  • \$\begingroup\$ These 2 brackets match, which seems like a strange thing to do. Is that intentional? \$\endgroup\$
    – Anko
    Commented Mar 5, 2015 at 12:57
  • \$\begingroup\$ @Anko Yeah you are right it's weird but when I take if (pos.x < 0) pos.x = 0 etc out of pos.add(direction) the player immediately flies out of the screen... \$\endgroup\$
    – Harry
    Commented Mar 5, 2015 at 13:51
  • \$\begingroup\$ Not sure, cause you're doing very weird java stuff here, but aren't your brackets defining a kind of method initialization block, that would explain why the code is executed only once ? (docs.oracle.com/javase/tutorial/java/javaOO/initial.html) \$\endgroup\$
    – Khopa
    Commented Mar 5, 2015 at 14:10
  • \$\begingroup\$ @Anko I edited the code a bit and took the bracket out but now there's a new problem. \$\endgroup\$
    – Harry
    Commented Mar 5, 2015 at 15:34

1 Answer 1

1
\$\begingroup\$

The issue is the else condition after you check the A and D keys, since if no key is pressed it will reset the direction to 0, 0 every time the update() method is called. Instead of calling moveLeft() and moveRight() in the touchDown and touchUp you should keep track of each pointer passed by the touchDown and touchUp methods and check whether the pointers are in the zones for a left or right movement in the update() method.

For example, create a class Pointer:

public class Pointer {
    public int x = 0, y = 0;
    public boolean down = false;
}

Then, create an array of pointers, touches[], in either the game class or the Player class to keep track of the touches. The length of touches[] should be however many touches you plan on recognizing, I usually use 10 just as a safe maximum. It would be best to put your array in the class that is the InputProcessor, which seems to be your Player class although it is typically the game class. Your touchDown, touchDragged and touchUp methods would change the values of x, y, and down for the Pointer at its index in touches[]. Then in update() iterate through the array and check for each touch.

For example:

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    if (pointer < touches.length){
        touches[pointer].x = screenX;
        touches[pointer].y = screenY;
        touches[pointer].down = true;
        return true;
    }
    return false;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    if (pointer < touches.length){
        touches[pointer].x = screenX;
        touches[pointer].y = screenY;
        touches[pointer].down = false;
        return true;
    }
    return false;

@Override
public boolean touchDragged(int screenX, int screenY, int pointer, int button) {
    if (pointer < touches.length){
        touches[pointer].x = screenX;
        touches[pointer].y = screenY;
        return true;
    }
    return false;
}

Side Notes: It seems like your update() method would only work with a fixed framerate, which may make movement speeds different on different devices unless a fixed framerate loop is implemented elsewhere in the code. In addition, you may want to move Gdx.input.setInputProcessor(this) to the constructor of the Player class.

\$\endgroup\$
6
  • \$\begingroup\$ Thanks for your answer. How exactly would I go about keeping track of each pointer as you say? I'm not even sure what you mean to be honest. \$\endgroup\$
    – Harry
    Commented Mar 5, 2015 at 16:06
  • \$\begingroup\$ @Harry I updated the answer with my suggestion. \$\endgroup\$ Commented Mar 5, 2015 at 16:20
  • \$\begingroup\$ Thanks again. Sorry if this is a stupid question but do I create the array touches[] in the Pointer class...? \$\endgroup\$
    – Harry
    Commented Mar 5, 2015 at 17:29
  • \$\begingroup\$ Not at all @Harry . I updated the answer to cover where the creation of touches[] should be. It seems strange to me that your Player class implements InputProcessor instead of whatever game class you're using, I would personally pass a reference to the game class in the constructor of Player and then use that reference to access touches[] while the game class instead implements InputProcessor. \$\endgroup\$ Commented Mar 5, 2015 at 17:41
  • \$\begingroup\$ thanks again for your help, I'm still trying to do it how you said but I'm struggling a bit, in the meantime I was wondering about what you said originally about the else condition causing the problem. How come it wasn't causing the same problem for the keyboard input? Keyboard input works exactly how I want it to and I still don't understand why it messes up when touch is implemented? \$\endgroup\$
    – Harry
    Commented Mar 7, 2015 at 12:30

Not the answer you're looking for? Browse other questions tagged .