how to make key press not pause? [duplicate]

2019-09-19 18:40发布

问题:

This question already has an answer here:

  • Java KeyListener stutters 3 answers

Okay, so I am making a 2D side scroller game for school. It is pretty much just like Mario (well, that is my hope for when I finish.) When I press the right arrow key to move my player along the map, he moves once, pauses, and then begins to smoothly move a lot. I think this is because of the pause that is in all apple laptops when you hold a key down, but I do not know how to get around this for my game. Any advice? Thank you.

回答1:

One solution is to set boolean keyUP = true inside the keypressed method and keyUP = false inside the keyreleased method. This way once the key has been pressed your game registers this as "keep moving up" until you release the key, instead of "Up was pressed move up, up was pressed move up....". This removes that initial lag (very noticable on linux) on input.

From our game:

private boolean up, down, left, right;

public void keyReleased(KeyEvent e) {
    switch (e.getKeyCode()) {
    case KeyEvent.VK_S:
        down = false;
        break;
    case KeyEvent.VK_W:
        up = false;
        break;
    case KeyEvent.VK_A:
        left = false;
        break;
    case KeyEvent.VK_D:
        right = false;
        break;
    }
}


public void keyPressed(KeyEvent e) {
    switch (e.getKeyCode()) {
    case KeyEvent.VK_S:
        down = true;
        break;
    case KeyEvent.VK_W:
        up = true;
        break;
    case KeyEvent.VK_A:
        left = true;
        break;
    case KeyEvent.VK_D:
        right = true;
        break;


回答2:

Although you have not sent any code snippet I can assume the following. I think that you have implemented key listener that does something when key is pressed. If user remains pressing the key your program gets the second event after some delay and then starts getting the events faster.

This is not what you need. You probably should hold some kind of application state keyIsPressed that is changed only once when the key is down (not pressed) first time. Then turn this variable off only when key is up. When key is down first time start background thread that moves your object and checks the flag keyIsPressed periodically to know when to stop.

Good luck to become a competitor of Mario... :)



回答3:

  • If this is a Swing GUI, then use Key Bindings, not a key listener,
  • start a Swing Timer on key press
  • and stop it on key release.


回答4:

All KeyEvents are integers, so you can make boolean[] which will store all changes in KeyEvents. For Java2d am using something like this:

import java.awt.KeyEventDispatcher;
import java.awt.event.KeyEvent;

public final class Keyboard implements KeyEventDispatcher {

    public static boolean[] keyPressed = new boolean[256];
    public static boolean[] keyHold = new boolean[256];
    public static boolean[] keyReleased = new boolean[256];

    public static void update() {
        for (int i=0; i<128; i++) {
            keyPressed[i] = false;
            keyReleased[i] = false;
        }
    }

    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getID()==KeyEvent.KEY_PRESSED) {
            keyHold[e.getKeyCode()] = true;
            keyPressed[e.getKeyCode()] = true;
        }
        else if (e.getID()==KeyEvent.KEY_RELEASED) {
            keyHold[e.getKeyCode()] = false;
            keyReleased[e.getKeyCode()] = true;
        }
        return false;
    }

}

I am calling update() after each frame.



标签: java keyevent