Устранение задержки при запуске нажатия клавиши

11

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

Таким образом, в основном, когда я нажимаю (например, в течение очень длительного времени) Up, мой объект будет двигаться на 1 единицу вверх, а не двигаться (в течение примерно 1 секунды), а затем непрерывно двигаться на 1 единицу вверх (без каких-либо задержек).

В настоящее время я использую это для перемещения объекта (SDL2):

while (SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_UP:
            //Move object 1 unit up
            break;
        //Other unrelated things omitted
        }
        break;
    //Omitted other cases
    }
}

Я хотел бы убрать задержку, чтобы объект мог сразу же двигаться Upочень быстро. Есть какой-либо способ сделать это?

Rakete1111
источник

Ответы:

19

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

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


источник
Не лучше ли слушать оконные сообщения? Используя опрос, я иногда пропускаю очень короткие нажатия клавиш, и эта проблема усугубляется, когда частота кадров низкая.
Рой Т.
@RoyT. Это действительно зависит от вашей игры и от того, какое действие вы хотите активировать клавишей. Если нажатие клавиши является одноразовой вещью, наподобие клавиши «действие», которая закрывает диалог, тогда очередь сообщений - это правильный подход - вы хотите прослушивать атомарное событие. - Если, с другой стороны, состояние ключа представляет текущее состояние, например, клавиша «перемещение», логика обычно while key UP is down move 30 units per second- и в секунду имеет смысл, когда у вас есть измеримое время между нажатием клавиши «вверх» и «вверх» - обычно более одного кадра.
Falco
@RoyT. Вы также можете прослушивать сообщения (и использовать их для обновления собственного массива состояний клавиатуры); Я решил предложить этот подход для его простоты. Конечно, вы можете написать еще один ответ. Важной частью является просто не полагаться на сообщения операционной системы для проверки , если ключ непрерывно вниз, потому что это то, что цепи вы к ключевой OS скорость повтора.
И под кадром вы подразумеваете игровой тик, а не видеокадр, верно? Потому что мы не плебс и не кодируем игровую логику в цикле рендеринга. :-)
corsiKa
@JoshPetrie Я полностью согласен, просто хотел бы указать на это небольшое предостережение, если вам нужно проверить «щелчок» вместо «нажатие». :)
Рой Т.
10

Альтернативный способ (подход Джоша тоже великолепен!) - установить логическое значение SDL_KEYDOWNи, возможно, игнорировать все повторяющиеся ключевые события. Это вы можете сделать, проверив repeatчлен ключевого события.

Тогда вы могли бы реализовать свой собственный таймер, который не должен быть чем-то необычным, и реализовать повторение клавиш самостоятельно. Вы можете запустить действие прямо из таймера или даже сгенерировать SDL_KEYDOWNсобытие и объединить решения.

Tyyppi_77
источник