Java: как определить, удерживается ли клавиша в течение определенного времени, без проверки каждого цикла - PullRequest
2 голосов
/ 21 сентября 2011

РЕДАКТИРОВАТЬ: Обратите внимание на других, преждевременная оптимизация является корнем всех зол! Если бы я не пытался оптимизировать каждый аспект моего кода (это была нормальная фаза!), Я сделал бы хорошую, читаемую программу, которую могли бы поддерживать и понимать другие.


В каждом цикле (1/60 секунды) класс Player проверяет класс Game, чтобы определить, какая клавиша нажата. Если игрок не направлен в правильную сторону, он поворачивается лицом в правильную сторону, иначе он движется в этом направлении. .

К сожалению, это означает, что если вы хотите повернуться, а не двигаться, вы должны нажать клавишу менее чем на 2/60 секунды (две петли). Код для проверки, какая клавиша нажата, находится ниже и ссылка на полный исходный код и встроенный пример ниже.

public class Game extends RenderableObject
{
    public static final byte NONE = 0;
    public static final byte UP = 1;
    public static final byte RIGHT = 2;
    public static final byte DOWN = 3;
    public static final byte LEFT = 4;

    public byte key = NONE;

    public Game()
        {
        }

    @Override
    public void keyPressed(KeyEvent ke)
        {
            if (!paused)
                {
                    if (ke.getKeyCode() == 38) // '^ key'
                        {
                            key = UP;
                            return;
                        }
                    else if (ke.getKeyCode() == 40) // 'v key'
                        {
                            key = DOWN;
                            return;
                        }
                    if (ke.getKeyCode() == 37) // '< key'
                        {
                            key = LEFT;
                            return;
                        }
                    else if (ke.getKeyCode() == 39) // '> key'
                        {
                            key = RIGHT;
                            return;
                        }
                }
        }

    @Override
    public void keyReleased(KeyEvent ke)
        {
            if (ke.getKeyCode() == 38) // '^ key'
                {
                    if (key == UP)
                        key = NONE;
                    return;
                }
            else if (ke.getKeyCode() == 40) // 'v key'
                {
                    if (key == DOWN)
                        key = NONE;
                    return;
                }
            if (ke.getKeyCode() == 37) // '< key'
                {
                    if (key == LEFT)
                        key = NONE;
                    return;
                }
            else if (ke.getKeyCode() == 39) // '> key'
                {
                    if (key == RIGHT)
                        key = NONE;
                    return;
                }

        }

Ссылка на полный исходный код и встроенный пример: (ну ссылка на страницу со ссылкой на скачивание в любом случае!

ВНИМАНИЕ: Я НУБ, если мои соглашения об именах отключены ... пожалуйста, не делайте мне больно!

http://troygametwodee.blogspot.com/2011/09/latest-build-21092011.html

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

В идеале я бы хотел иметь возможность проверить какую-то логическую переменную в игровом классе, чтобы игрок двигался в этом направлении только тогда, когда верно значение bool, но я тоже потерпел неудачу: (

Так что, если у кого-нибудь есть какие-либо предложения, я был бы очень рад :))

Заранее большое спасибо

Ответы [ 3 ]

2 голосов
/ 22 сентября 2011

Хорошо, так как я решил проблему, оставив возможным движение жидкости:

Сначала я добавил булеву переменную под названием «удерживается».Само по себе это было бесполезно, поэтому я также добавил числовую переменную под названием "timeHeld".Каждый раз, когда нажималась клавиша, я сбрасывал «timeHeld» в ноль и делал «Hold» == false, и помещал следующий код в мой цикл.

if (timeHeld < 20)
    timeHeld++;
else
    held = true;

Так в моем классе игрока, когда решался, каким образомдля перемещения он вызывает «Game.key», чтобы определить, какая клавиша нажата, тогда, если «удержанный» логический параметр истинен (что происходит через одну треть секунды), игрок идет в этом направлении, в противном случае игрок остается там, где он находится.на экране и просто изменил направление, в котором он смотрел.

Это работало до некоторой степени, но каждый раз, когда я менял направление, переменная «удерживалась» снова устанавливалась в ноль.Это означает, что каждый раз, когда я поворачиваюсь, меня задерживают на треть секунды, очень раздражает!

Так я делал это:

if (ke.getKeyCode() == 38) // '^ key'
        {
            if (key == NONE)
                {
                    held = false;
                    timeHeld = 0;
                }
            key = UP;
            return;
    }

это означает, что, пока нажата клавиша со стрелкой«удерживается» остается верным, поэтому, как только игрок начинает движение, поворот на поворот не задерживается.

Это сработало абсолютно идеально, как и было, поэтому я и добавил другую переменную.Поскольку я использую только средний палец для клавиш ВВЕРХ и ВНИЗ, когда я играю с помощью клавиш со стрелками или «wasd», в итоге я отпускаю все клавиши, когда переключаюсь с движения на север на юг.В этом случае с кодом, как описано выше, я остановился на треть секунды SO, чтобы исправить это, я добавил переменную с именем «delay»

Когда ключ отпущен, задержка установлена ​​на 10(петли), каждый цикл, который я вызываю:

if (delay > 0)
    delay--;

, затем, когда нажимается клавиша, я звоню:

if (ke.getKeyCode() == 38) // '^ key'
    {
        if (key == NONE && delay == 0)
                {
                    held = false;
                        timeHeld = 0;
                }
            key = UP;
            return;
        }

Это означает, что «удерживается» всегда устанавливается в «ложь», когданажата клавиша направления, и в то время, когда она была нажата, других клавиш со стрелками вниз не было, а задержка равна 0. Это дает мне задержку в 10 циклов между отпусканием всех клавиш со стрелками и нажатием еще одной кнопки до того, как для параметра «hold» установлено значение false..

В замешательстве?Я!но это работает, любой другой, у кого есть эта проблема, может либо перейти по ссылке на мой блог, где должен быть последний рабочий источник, либо просто попросить меня объяснить, какие биты вы не получите: D

1 голос
/ 21 сентября 2011

Более точное описание того, что вы пытаетесь достичь, поможет.

Однако, если я правильно понимаю, вы можете сохранить краткую историю того, какой ключ не активен, например, сохранить значение ключа для последних пятипетли.Затем вы можете выполнить определенные действия, если хотя бы определенное количество предыдущих значений соответствует определенному ключу.

0 голосов
/ 21 сентября 2011

попробуйте удерживать объект значения с логическим значением для всех ваших действий / нажатий клавиш в нем.Логическое значение будет истинно для keydown и false для keyup.После выполнения действий с ключами вы можете обновить объект-значение на true / false только для соответствующего ключа.

Затем, когда ваш цикл обновления игры запускается, вы можете проверить, какие ключи в данный момент недоступны.

...