Многократный ввод с клавиатуры C # WPF - PullRequest
2 голосов
/ 06 апреля 2010

Я пишу клон тетриса в WPF.Если я удерживаю клавишу со стрелкой вправо, текущий фрагмент сдвигается вправо.Для удобства воспроизведения я хочу позволить пользователю нажимать другую клавишу (например, клавишу F) и вращать движущийся элемент , не отпуская сначала правую клавишу со стрелкой .В настоящее время, когда я делаю это, часть перестает сдвигаться.

Моя первая базовая попытка - подключиться к

Window_PreviewKeyDown(object sender, KeyEventArgs e)

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

Мой текущий код Здесь

Ответы [ 4 ]

3 голосов
/ 06 апреля 2010

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

Исправьте это, присвоив каждому игровому объекту статус движения. Используйте событие KeyDown, чтобы изменить его. И событие KeyUp, чтобы сбросить его, если значение состояния движения по-прежнему соответствует ключу. В вашем игровом цикле обновите позиции игровых объектов в зависимости от их состояния движения. Вы делаете это с фиксированной скоростью, запускаемой таймером.

Состояние движения также должно указывать на «падение». Теперь вы можете просто усложнить игру по мере прохождения уровней, уменьшив частоту таймера. Кусочки падают быстрее. И клавиатура становится более отзывчивой, давая пользователю возможность все же выиграть уровень.

2 голосов
/ 06 апреля 2010

Также должно существовать событие KeyUp, и используя KeyDown и KeyUp, вы можете достичь желаемого эффекта.Это можно сделать несколькими способами.

Один из них - позволить событию KeyDown инициировать повторяющееся действие и позволить KeyUp отменить его.

Другой способ - сохранить, используются ли определенные ключи.удерживается.Держите список ключей и включайте их при KeyDown и выключайте при KeyUp.В основном цикле игры вы будете запускать события, соответствующие всем клавишам, которые в данный момент отключены.

Пример:

bool[] heldDown = new bool[256]; // One index for the keycode of each key

void Window_PreviewKeyDown(object sender, KeyEventArgs e) {
    heldDown[e.KeyCode] = true;
}    
void Window_PreviewKeyUp(object sender, KeyEventArgs e) {
    heldDown[e.KeyCode] = false;
}    

И затем вы проходите через «holdDown» в вашем основном цикле и запускаете события для каждого значащего ключа, который удерживается:

if (heldDown[Key.F])
    MainController.TriggerPieceEvent(Constants.PieceEvents.RotateClockwise);
if (heldDown[Key.Left])
    MainController.TriggerPieceEvent(Constants.PieceEvents.ShiftLeft);
// etc...
1 голос
/ 06 апреля 2010

Вам нужны состояния.Создайте некоторые переменные, такие как 'RightArrowPressed' и 'RotateButtonPressed'

в Key_Down, проверьте, нажата ли клавиша, если это так, установите для соответствующей переменной значение true.

В key_up сделайте то же самое, но установитеих значение равно false.

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

1 голос
/ 06 апреля 2010

Windows будет повторять события только для последней нажатой клавиши. Кроме того, задержка перед первым повторением клавиши, а также скорость ее повторения зависят от настроек, которые обычно оптимизированы для набора текста, а не для игр. Поэтому для игр лучше всего их полностью игнорировать и по-своему реализовать «повторяющиеся» клавиши.

По сути, вам придется сохранять состояния (нажатые или отпущенные) интересующих вас клавиш и изменять их при получении события KeyDown или KeyUp. Затем, в каком-то таймере, вам придется проверять состояния и события срабатывания для каждого ключа, который не работает в этот момент. Если этот таймер происходит на уровне контроллера или в пользовательском интерфейсе, зависит от вашей архитектуры :-)

Вы можете добавить дополнительные проверки, например, когда левая и правая клавиши опущены, чтобы игнорировать обе, в противном случае фигура будет неоднократно перескакивать влево и вправо.

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