#c #winapi #input #user-input #xinput
#c #winapi #ввод #пользовательский ввод #xinput
Вопрос:
Я создаю игру на основе кадров в секунду. В настоящее время у меня есть функция wnd_proc для захвата всех событий для ввода (WM_MOUSEMOVE, WM_KEYUP, WM_KEYDOWN, …). Моя мышь используется для перемещения камеры, как в fps. Он отлично работает, когда я только перемещаю мышь. Но когда я нажимаю на клавиши для перемещения персонажа и одновременно перемещаю мышь, возникает задержка при обнаружении движения мыши в игре. Я также замечаю задержку при нажатии нескольких клавиш.
Для событий клавиатуры вместо использования моего собственного класса ввода для проверки того, нажаты ли клавиши, я использую GetAsyncKeyState() для чтения содержимого клавиатуры, и это устраняет задержку с несколькими клавишами. Но моя мышь по-прежнему является проблемой. Существует ли асинхронная функция для перемещения мыши?
—РЕДАКТИРОВАТЬ—
Это мой класс системы ввода, который вызывается во время функции wndproc.
class InputSystem : public System
{
...
...
...
void ProcessInput(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LPBYTE lpb;
UINT dwSize;
RAWINPUT *raw;
switch (message)
{
case WM_INPUT:
{
GetRawInputData((HRAWINPUT)lParam,
RID_INPUT,
NULL,
amp;dwSize,
sizeof(RAWINPUTHEADER));
lpb = new BYTE[dwSize];
if (lpb == NULL)
return;
if (GetRawInputData((HRAWINPUT)lParam,
RID_INPUT,
lpb,
amp;dwSize,
sizeof(RAWINPUTHEADER)) != dwSize)
MessageBox(hWnd, L"GetRawInputData returning wrong size!", L"Orhhor! Bao zha liao!", MB_OK);
raw = (RAWINPUT*)lpb;
if (raw->header.dwType == RIM_TYPEKEYBOARD)
{
if (raw->data.keyboard.Message == WM_KEYDOWN ||
raw->data.keyboard.Message == WM_SYSKEYDOWN)
{
input.ReadInput(raw->data.keyboard.VKey);
}
else if (raw->data.keyboard.Message == WM_KEYUP ||
raw->data.keyboard.Message == WM_SYSKEYUP)
{
input.ResetInput(raw->data.keyboard.VKey);
}
}
delete[] lpb;
return;
}
В то время как ниже приведен мой класс ввода
class Input
{
bool keys[256];
bool prevKeys[256];
...
...
...
}
void Input::InitInput()
{
...
...
...
auto hWnd = CORE->GetSystem<WindowManager>()->GetWindowHandle();
RAWINPUTDEVICE Rid[2];
Rid[0].usUsagePage = 0x01;
Rid[0].usUsage = 0x06; //keyboard
Rid[0].dwFlags = RIDEV_INPUTSINK;
Rid[0].hwndTarget = hWnd;
if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == false)
assert("Keyboard not registered.");
Rid[0].usUsagePage = 0x01;
Rid[0].usUsage = 0x02; //mouse
Rid[0].dwFlags = RIDEV_INPUTSINK;
Rid[0].hwndTarget = hWnd;
if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[1])) == false)
assert("Mouse not registered.");
for (int i = 0; i < 256; i)
{
keys[i] = false;
prevKeys[i] = false;
}
}
void Input::ReadInput(WPARAM w)
{
keys[w] = true;
return;
}
void Input::ResetInput(WPARAM w)
{
keys[w] = prevKeys[w] = false;
return;
}
bool Input::KeyPressed(int key)
{
if (!prevKeys[key] amp;amp; keys[key])
{
prevKeys[key] = true;
return true;
}
return false;
}
bool Input::KeyDown(int key)
{
return keys[key];
}
Комментарии:
1. Вы можете использовать GetCursorPos() .
2. ого! Спасибо! Я больше не получаю никаких задержек! Большое спасибо!
3. Рассмотрите возможность использования API необработанного ввода для получения
WM_INPUT
сообщений непосредственно от драйверов клавиатуры / мыши.4. @RemyLebeau привет, я изменил свой код, чтобы теперь использовать rawinput, но при наведении мыши и нажатии на клавиатуру будет огромная задержка. ошибочна ли моя реализация?