как сделать, чтобы нажатие клавиши не делало паузы?

Итак, я делаю 2D-скроллер для школы. Это очень похоже на Марио (ну, это моя надежда, когда я закончу). Когда я нажимаю клавишу со стрелкой вправо, чтобы перемещать моего игрока по карте, он перемещается один раз, делает паузу, а затем начинает плавно двигаться много. Я думаю, это из-за паузы, которая есть во всех яблочных ноутбуках при зажатии клавиши, но я не знаю, как это обойти для своей игры. Любой совет? Спасибо.


person GrayW3    schedule 05.05.2013    source источник
comment
@ syb0rg: да, и в этом решении используются привязки клавиш и таймер Swing.   -  person Hovercraft Full Of Eels    schedule 06.05.2013


Ответы (4)


Одним из решений является установка boolean keyUP = true внутри метода keypressed и keyUP = false внутри метода keyreleased. Таким образом, после нажатия клавиши ваша игра регистрирует это как "keep moving up", пока вы не отпустите клавишу, вместо "Up was pressed move up, up was pressed move up....".. Это устраняет начальную задержку (очень заметную в Linux) при вводе.

Из нашей игры:

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;
person arynaq    schedule 05.05.2013
comment
Это сработало! Большое спасибо! - person GrayW3; 06.05.2013

Хотя вы не прислали ни одного фрагмента кода, я могу предположить следующее. Я думаю, что вы реализовали прослушиватель клавиш, который что-то делает при нажатии клавиши. Если пользователь продолжает нажимать клавишу, ваша программа получает второе событие после некоторой задержки, а затем начинает получать события быстрее.

Это не то, что вам нужно. Вероятно, вам следует удерживать какое-то состояние приложения keyIsPressed, которое изменяется только один раз, когда клавиша нажата (не нажата) в первый раз. Затем отключите эту переменную только тогда, когда ключ нажат. Когда ключ нажат в первый раз, запустите фоновый поток, который перемещает ваш объект и периодически проверяет флаг keyIsPressed, чтобы знать, когда остановиться.

Удачи стать конкурентом Марио... :)

person AlexR    schedule 05.05.2013

  • Если это графический интерфейс Swing, используйте привязки клавиш, а не ключевой прослушиватель,
  • запустить таймер Swing при нажатии клавиши
  • и остановите его при отпускании ключа.
person Hovercraft Full Of Eels    schedule 05.05.2013

Все KeyEvents являются целыми числами, поэтому вы можете сделать boolean[], который будет хранить все изменения в KeyEvents. Для Java2d я использую что-то вроде этого:

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;
    }

}

Я вызываю update() после каждого кадра.

person Mac70    schedule 05.05.2013