Java: множественный ввод с клавиатуры в течение периода таймера

В моей школе в качестве задания я должен сделать улучшенную версию игры "ЗМЕЯ".

(Я не буду добавлять дальнейшее описание, так как это очень известно)

У меня проблемы с вводом данных с клавиатуры.

Ниже приведены краткие сведения о моем коде.


КОД

Вступительная часть

private final int DELAY = 500; //500ms every event

timer = new Timer(DELAY, this);
timer.start();

Часть ввода с клавиатуры (ПРОБЛЕМА)

int key=e.getKeyCode();

if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
    leftDirection = true;
    upDirection = false;
    downDirection = false;
}

if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
    rightDirection = true;
    upDirection = false;
    downDirection = false;
}

if ((key == KeyEvent.VK_UP) && (!downDirection)) {
    upDirection = true;
    rightDirection = false;
    leftDirection = false;
}

if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
    downDirection = true;
    rightDirection = false;
    leftDirection = false;
}

ИСПРАВИТЬ

Моя программа неправильно обрабатывает несколько быстрых вводов.

Например, предположим, что змея двигалась вправо.

оооооо (->)

Если я быстро нажимаю «вверх» и «влево» во время ЗАДЕРЖКИ (которая составляет 500 мс),

затем голова змеи уходит влево и движется по ее телу.

оооооо (‹-)

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


УСЛОВИЕ

Профессор дал код шаблона для частей ввода с клавиатуры, подобных этому.

private class TAdapter extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {

        //Keyboard input part (PROBLEM)

person Donggun Jung    schedule 03.06.2016    source источник
comment
Какой вопрос ?   -  person Nir Alfasi    schedule 03.06.2016
comment
@alfasin Как мне изменить часть ввода с клавиатуры, чтобы решить эту проблему?   -  person Donggun Jung    schedule 03.06.2016


Ответы (1)


Вам понадобится два набора полей. Один набор описывает последнюю нажатую клавишу направления, а другой описывает фактическое направление движения, реализованное последним в действии таймера:

private boolean leftPressed;
private boolean rightPressed;
private boolean upPressed;
private boolean downPressed;

private boolean movingLeft;
private boolean movingRight;
private boolean movingUp;
private boolean movingDown;

Как и следовало ожидать, поля «Pressed» устанавливаются только KeyListener.

Затем действие Timer должно прочитать эти поля *Pressed и соответствующим образом установить движущиеся* поля. Это позволяет вашему KeyListener запрещать изменение направления на основе последнего реализованного направления, а не только последней нажатой клавиши:

if (key == KeyEvent.LEFT && !movingRight) {
    leftPressed = true;
    rightPressed = false;
    upPressed = false;
    downPressed = false;
}

Вы можете обнаружить, что использовать перечисление проще, чем поддерживать группу из четырех логических значений. Например:

private enum Direction { LEFT, RIGHT, UP, DOWN }

private Direction lastKeyPressed;
private Direction movement;
person VGR    schedule 03.06.2016
comment
Удивительно. Это действительно помогло мне практиковать enum. Большое спасибо. - person Donggun Jung; 04.06.2016
comment
Однако, когда он направляется вправо, если я быстро нажму вверх и влево (во время ЗАДЕРЖКИ), он пойдет вверх. Как я могу предотвратить это? (только последний ввод) - person Donggun Jung; 04.06.2016
comment
@DonggunJung Возможно, вы захотите опубликовать новый вопрос об этом, который включает ваш последний код. - person VGR; 05.06.2016