Должен ли я использовать конвейер DirectInput или Windows?

Я работаю над С++ DirectX 2D-игрой, и мне нужно вводить клавиатуру и мышь.
Википедия говорит:

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

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

Спасибо

Ответы

Ответ 1

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

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

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, чтобы вы могли периодически просыпаться, даже если нет сообщений для обработки, но сразу же, когда есть сообщения.

Ответ 2

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

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

Ответ 3

FYI: Re John Knoeller отвечает... упрощенная система сообщений выглядит так:

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

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

Ответ 4

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

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

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

Ответ 5

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

Для деталей я согласен с ответом Джона Кноллера.

Ответ 6

Использовать непосредственное использование directinput при особых обстоятельствах

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

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

Особые обстоятельства - используйте directinput

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

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

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

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

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

Ответ 7

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

Кроме того, у вас есть поддержка для gamecontrollers, джойстиков и т.д. из коробки.