2010-01-29 3 views
13

Я работаю над C++ DirectX 2D-игрой, и мне нужен ввод с клавиатуры и мыши.
Википедия говорит:Должен ли я использовать коннектор сообщений DirectInput или Windows?

Microsoft рекомендует новые приложения используют цикл обработки сообщений Windows, для клавиатуры и мыши ввода вместо DirectInput

Так как я должен использовать его?
У меня классный класс GameScreen заботится о чертеже и обновлении (логике игры), я вызываю методы Draw и Update внутри цикла сообщений Windows.

Благодаря

ответ

14

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

Ваше типичное сообщение насос выглядит следующим образом:

while (GetMessage(&msg, NULL, 0, 0)) 
{ 
    if (WM_QUIT == msg.message) 
     break; 
    TranslateMessage(&msg); // post a WM_CHAR message if this is a WM_KEYDOWN 
    DispatchMessage(&msg); // this sends messages to the msg.hwnd 
} 

Для игры, ваш насос может выглядеть как этот

while (true) 
{ 
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD)) 
    { 
     bool fHandled = false; 
     if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST) 
     fHandled = MyHandleMouseEvent(&msg); 
     else if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) 
     fHandled = MyHandleKeyEvent(&msg); 
     else if (WM_QUIT == msg.message) 
     break; 

     if (! fHandled) 
     { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
     } 
    } 
    else 
    { 
     // if there are no more messages to handle right now, do some 
     // game slice processing. 
     // 
    } 
} 

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

+4

Я хотел бы знать, почему я не должен использовать DirectInput. Спасибо – Adir

+1

Отправлено Alex в http://stackoverflow.com/questions/2165230/should-i-use-directinput-or-windows-message-loop/2168067#2168067 – bobobobo

1

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

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

Я не могу сказать много о вашем конкретном сценарии, конечно, - только мой 2c.

+1

Неверно, что события клавиатуры и мыши переходят в окно фокусировки. События клавиатуры отправляются в окно фокусировки _ вашим сообщением pump_ (это то, что делает DispatchMessage). События мыши идут в окно под курсором. –

+0

Справа. Благодаря! Я изначально комментировал только клавиатуру и только потом «исправил» ее на клавиатуре/мыши. –

-1

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

У вас есть поддержка для gamecontrollers, джойстиков и т. Д. Из коробки.

+1

DirectInput не является более низкой латентностью для событий клавиатуры и мыши. Но это дает вам более последовательную модель ввода, если вы позже захотите поддерживать джойстики и т. Д. –

+0

Вы абсолютно прав, но я имел в виду, что DirectInput (и XInput, который является потомком DInputs) имеет более низкую задержку, чем сообщения Windows. – DarthCoder

+1

Но не для ввода клавиатуры и мыши.DirectInput - это всего лишь оболочка интерфейса Win32 API для клавиатуры и мыши. –

1

Да, сообщение MSDN верное. Используя сообщения Windows, вы можете использовать многоязычную поддержку (для любой клавиатуры, которую пользователь может использовать)/личные настройки пользователя (правая кнопка мыши вместо левой) и т. Д., Что вам нужно отказаться от использования DirectInput/XInput , Используйте только те 2 для поддержки геймпада/джойстика. Для остальных просто используйте сообщения Windows.

Для получения более подробной информации я согласен с ответом Джона Кноуэра.

4

DirectInput устарел по уважительным причинам.Как я знаю, он создает дополнительный поток и просто запрашивает интерфейс Windows Raw Input. Для лучшей производительности я бы использовал Raw Input напрямую.

Если производительность не является проблемой для вас (и я думаю, что это так для 2D-игры на текущем оборудовании), следуйте советам Microsoft и используйте оконные сообщения, как описано Джоном Кнуллером.

+0

Не могли бы вы обосновать «только запросы Windows» Сырой вход интерфейс "бит дальше (возможно, с ссылкой)? – bobobobo

3

FYI: Re ответ Джона Knoeller в ... упрощенным сообщение насос выглядит следующим образом:

while (GetMessage(&msg, NULL, 0, 0)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

Испытание WM_QUIT, что он включал никогда не может быть правдой, потому что GetMessage возвращает ноль, когда WM_QUIT принимается. Однако тестирование WM_QUIT в цикле PeekMessage -, потому что PeekMessage возвращает true/false, было ли сообщение возвращено или нет. Поскольку GetMessage блокируется до тех пор, пока сообщение не будет возвращено, оно может иметь другое возвращаемое значение.

0

Используйте только использовать DirectInput при особых обстоятельствах

Хорошая вещь о цикле обработки сообщений Windows, используемой с GetMessage является то, что он использует 0% использование центрального процессора. Если вы выполняете непроцессорные интенсивные вещи, такие как ожидание ключа от пользователя, сбор данных от пользователя, например, в базе данных или в налоговой программе, или даже в текстовом редакторе, имеет смысл просто использовать сообщение Windows с getmessage. Я все вышеприведенные даты программы - это процесс, когда пользователь нажимает клавишу.

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

Специальные условия использования DirectInput

Если вам нужно: 1) Знайте, когда клавиша нажата и отпущена. Вы также можете не захотеть повторять ключи, обнаруженные как нажатия клавиш.
2) Обработать клавиши в фоновом режиме при переключении другой программы.

Если выполнено одно из указанных выше условий, используйте функцию directinput.

Если вы просто собираете данные от пользователя, вам нужно будет использовать команду sleep для приостановки выполнения программы. Вы хотите, чтобы программа имела 0% использования процессора в диспетчере задач, если программа просто сидит там, ожидая нажатия клавиш от пользователя.

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

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

Смежные вопросы