简体   繁体   English

(Windows C++) 如何在 FPS 游戏中模拟鼠标移动?

[英](Windows C++) How to simulate mouse movement in FPS games?

I'm trying to simulate mouse movement in FPS games, more specifically Valorant .我正在尝试模拟 FPS 游戏中的鼠标移动,更具体地说是Valorant I am aware of the SetCursorPos() function and the mouse_event() function, which both work fine for changing the cursor's position.我知道SetCursorPos() function 和mouse_event() function,它们都可以很好地更改光标的 Z4757FE07FD492A8BE0EA6A760D683D6E。 This works in FPS games that use the technique of constantly centering the cursor, but Valorant doesn't seem to do that.这适用于使用不断居中 cursor 技术的 FPS 游戏,但Valorant似乎没有这样做。 I wrote a program to constantly check my cursor's position (using GetCursorPos() ) and my cursor never got centered, if I moved the mouse to a corner and then kept moving it, my character kept rotating.我编写了一个程序来不断检查我的光标的 position (使用GetCursorPos() )和我的 cursor 从来没有居中,如果我将鼠标移动到一个角落然后继续移动它,我的角色会继续旋转。 So, how does Valorant sense that I'm moving my mouse when my cursor's position isn't changing, and how can I counter that and simulate mouse movement in Valorant ?那么,当我的光标的 position 没有改变时, Valorant是如何感知我正在移动鼠标的,我该如何应对这种情况并在Valorant中模拟鼠标移动?

By the way, don't worry - I'm not trying to cheat, just trying to make smooth motions in freecam for cinematic shots.顺便说一句,别担心——我不是想作弊,只是想在 freecam 中为电影镜头做出流畅的动作。

I'm not sure how Valorant is implemented, but I can use the RegisterRawInputDevices to get the mouse event when the cursor's position isn't changing:我不确定 Valorant 是如何实现的,但是当光标的 position 没有改变时,我可以使用RegisterRawInputDevices来获取鼠标事件:

#include <windows.h>
#include <iostream>

using namespace std;
BOOL registerTouchpadForInput(HWND hWnd)
{
    RAWINPUTDEVICE rid;
    rid.dwFlags = RIDEV_NOLEGACY | RIDEV_INPUTSINK;
    rid.usUsagePage = 1;                            
    rid.usUsage = 2;
    rid.hwndTarget = hWnd;
    return RegisterRawInputDevices(&rid, 1, sizeof(rid));
}

static LRESULT CALLBACK NVTouch_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    BOOL  registrationStatus = false;
    switch (message)
    {
    case WM_CREATE:
        registrationStatus = registerTouchpadForInput(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_INPUT:
        printf("WM_INPUT ");
        return DefWindowProc(hwnd, message, wParam, lParam);
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

int main()
{
    WNDCLASSEX wndclass = {
        sizeof(WNDCLASSEX),
        CS_DBLCLKS,
        NVTouch_WindowProc,
        0,
        0,
        GetModuleHandle(0),
        LoadIcon(0,IDI_APPLICATION),
        LoadCursor(0,IDC_ARROW),
        HBRUSH(COLOR_WINDOW + 1),
        0,
        L"myclass",
        LoadIcon(0,IDI_APPLICATION)
    };
    bool isClassRegistered = false;
    isClassRegistered = RegisterClassEx(&wndclass);
    if (isClassRegistered)
    {
        HWND window = CreateWindow(wndclass.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(0), NULL);
        if (window)
        {
            ShowWindow(window, SW_SHOWDEFAULT);
            MSG msg;
            while (GetMessage(&msg, 0, 0, 0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }
}

And then, use SendInput to simulate the relative mouse move at the border of the screen:然后,使用SendInput模拟鼠标在屏幕边缘的相对移动:

INPUT buffer;
ZeroMemory(&buffer, sizeof(buffer));
buffer.type = INPUT_MOUSE;
buffer.mi.dx = 10;
buffer.mi.dy = 10;
buffer.mi.mouseData = 0;
buffer.mi.dwFlags = MOUSEEVENTF_MOVE;
buffer.mi.time = 0;
buffer.mi.dwExtraInfo = 0;
while (1)
{
    Sleep(1000);
    SendInput(1, &buffer, sizeof(INPUT));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM