Я должен использовать DirectInput или цикл сообщения Windows?

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

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

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

Спасибо

14
задан Adir 29 January 2010 в 21:18
поделиться

6 ответов

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

Ваш типичный насос сообщений выглядит так:

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

14
ответ дан 1 December 2019 в 12:26
поделиться

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

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

-1
ответ дан 1 December 2019 в 12:26
поделиться

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

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

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

1
ответ дан 1 December 2019 в 12:26
поделиться

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

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

1
ответ дан 1 December 2019 в 12:26
поделиться

BOOST :: Вариант выставляет его типы через типы , который является списком MPL. Вы можете делать операции времени выполнения по спискам MPL с использованием MPL MPL :: for_each :

struct printer {
    template<class T> void operator()(T t) {
        std::cout << typeid(T).name() << std::endl;
    }
};

// ... 
typedef boost::variant<int, char> var;
boost::mpl::for_each<var::types>(printer());
-121--2814179-

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

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

5
ответ дан 1 December 2019 в 12:26
поделиться

К вашему сведению: Что касается ответа Джона Кнеллера ...упрощенный насос сообщений выглядит так:

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

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

3
ответ дан 1 December 2019 в 12:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: