Итак, я делаю 2D-скроллер для школы. Это очень похоже на Марио (ну, это моя надежда, когда я закончу). Когда я нажимаю клавишу со стрелкой вправо, чтобы перемещать моего игрока по карте, он перемещается один раз, делает паузу, а затем начинает плавно двигаться много. Я думаю, это из-за паузы, которая есть во всех яблочных ноутбуках при зажатии клавиши, но я не знаю, как это обойти для своей игры. Любой совет? Спасибо.
как сделать, чтобы нажатие клавиши не делало паузы?
Ответы (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;
Хотя вы не прислали ни одного фрагмента кода, я могу предположить следующее. Я думаю, что вы реализовали прослушиватель клавиш, который что-то делает при нажатии клавиши. Если пользователь продолжает нажимать клавишу, ваша программа получает второе событие после некоторой задержки, а затем начинает получать события быстрее.
Это не то, что вам нужно. Вероятно, вам следует удерживать какое-то состояние приложения keyIsPressed
, которое изменяется только один раз, когда клавиша нажата (не нажата) в первый раз. Затем отключите эту переменную только тогда, когда ключ нажат. Когда ключ нажат в первый раз, запустите фоновый поток, который перемещает ваш объект и периодически проверяет флаг keyIsPressed
, чтобы знать, когда остановиться.
Удачи стать конкурентом Марио... :)
- Если это графический интерфейс Swing, используйте привязки клавиш, а не ключевой прослушиватель,
- запустить таймер Swing при нажатии клавиши
- и остановите его при отпускании ключа.
Все 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() после каждого кадра.