0

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.

  • 3
    Not sure if it is the problem, but the way you are comparing String objects is wrong : https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – Arnaud Nov 02 '17 at 08:58
  • I know that's not correct, but it compares them correctly for some reason so I didn't fix it. –  Nov 02 '17 at 09:07
  • Any reason why keyPressed and keyReleased do the opposite? – MystyxMac Nov 02 '17 at 09:15
  • Setting keyPressed to 0 wasn’t working very well. For instance if I moved the player left, then switched to right, it would take about a second for the player to move right. Making it do the opposite makes left and right / up and down movement instant –  Nov 02 '17 at 09:30
  • Why does " I then hold DOWN.. and the player will moves down" is the expected behavior ? With your code, if you press both up and down, player shouldn't move. – Asoub Nov 02 '17 at 09:40
  • @Asiub That’s what I’m saying. It’s want it to do. I don’t know why it works like that. it should be setting velocity to 0 –  Nov 02 '17 at 09:42
  • I'm not sure how KeyEvent really works. My only advice is that you should debug both methods by logging the key pressed/or released and the current state of the object X and Y, after and before setting, and with timestamp. – Asoub Nov 02 '17 at 09:50

1 Answers1

0

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 .

Arnaud
  • 17,229
  • 3
  • 31
  • 44