user5544654
user5544654

Reputation:

Java: Player movement bug

Apologies in advance. I'm self taught and have only been learning for a month.

This is for a simple rectangle in a window that I move with WASD keys.

public LinkedList<Object> object;

public KeyInput(LinkedList<Object> object){
    this.object = object;
}

public void keyPressed(KeyEvent e){

    int key = e.getKeyCode();

        Object myPlayer = Main.object.get(0);

        if(myPlayer.getName() == "PlayerOne"){
            if(key == KeyEvent.VK_W) 
                myPlayer.setVelocityY(myPlayer.getVelocityY() - 5);
            if(key == KeyEvent.VK_S)
                myPlayer.setVelocityY(myPlayer.getVelocityY() + 5);
            if(key == KeyEvent.VK_D) 
                myPlayer.setVelocityX(myPlayer.getVelocityX() + 5);
            if(key == KeyEvent.VK_A)
                myPlayer.setVelocityX(myPlayer.getVelocityX() - 5);
        }

    if(key == KeyEvent.VK_ESCAPE) System.exit(0);
}

public void keyReleased(KeyEvent e){
    int key = e.getKeyCode();

        Object tempObject = Main.object.get(0);

        if(tempObject.getName() == "PlayerOne"){
            if(key == KeyEvent.VK_W) 
                tempObject.setVelocityY(tempObject.getVelocityY() + 5);
            if(key == KeyEvent.VK_S)
                tempObject.setVelocityY(tempObject.getVelocityY() - 5);
            if(key == KeyEvent.VK_D) 
                tempObject.setVelocityX(tempObject.getVelocityX() - 5);
            if(key == KeyEvent.VK_A)
                tempObject.setVelocityX(tempObject.getVelocityX() + 5);
        }
}

/////////////////////////////////////////////////////////////

public void setVelocityX(int velocityX){        
    this.velocityX = velocityX;
    //Prevent a speed higher than 5.
    if(this.velocityX > 5) this.velocityX = 5;
    if(this.velocityX < -5) this.velocityX = -5;
}
public void setVelocityY(int velocityY){
    this.velocityY = velocityY;
    if(this.velocityY > 5) this.velocityY = 5;
    if(this.velocityY < -5) this.velocityY = -5;}

Movement works exactly as I intended. No delay between keypresses, movement is smooth, and diagonal movement works. Problem is.. If I Hold UP, the player moves up as intended. I then hold DOWN.. and the player will moves down, also as intended. But when I release DOWN player will not move up even though I never released up. Then when I finally release UP, the player moves all the way to the bottom. Thank you.

If I key is pressed does it not update getVelocity? According to the math, holding up would set velocityX to -5. Then holding down adds +5 to velocityX. Thus making it 0. But the player moves down anyway. I've been trying to fix this for 10 hours. Any help would be amazing.

Upvotes: 0

Views: 221

Answers (1)

Arnaud
Arnaud

Reputation: 17534

The problem with keyPressed, is that many events will be sent for a given key, as long as it is maintained pressed.

What you could do is ignore the event if the last one was for the same pressed key .

In your class, you may declare some int to store the value of last key :

private int lastKey = 0;

Then use it this way (see the comments in the code) :

public void keyPressed(KeyEvent e){

    int key = e.getKeyCode();

    // if last key was the same one, ignore :
    if (key == lastKey) {
        return;
    }

    Object myPlayer = Main.object.get(0);

    if(myPlayer.getName().equals("PlayerOne")){
        if(key == KeyEvent.VK_W) 
            myPlayer.setVelocityY(myPlayer.getVelocityY() - 5);
        if(key == KeyEvent.VK_S)
            myPlayer.setVelocityY(myPlayer.getVelocityY() + 5);
        if(key == KeyEvent.VK_D) 
            myPlayer.setVelocityX(myPlayer.getVelocityX() + 5);
        if(key == KeyEvent.VK_A)
            myPlayer.setVelocityX(myPlayer.getVelocityX() - 5);
    }

    // set the current key as the last key
    lastKey = key;

    if(key == KeyEvent.VK_ESCAPE) System.exit(0);
}

Also, the String comparison has been fixed in this example .

Upvotes: 0

Related Questions