I am trying to implement an object that can be dragged with the mouse cursor, but it seems to very slightly lag behind the cursor when I do.
In earlier versions, this caused a problem where if the cursor and object moved fast enough, it would lag behind so far that they were no longer overlapping, causing the object to “drop” from the cursor. Though I fixed this by improving the “grab” logic, the lag still creates a noticeable visual error; I’ve included a video which shows it. The lag is fairly subtle, but if you look at the position of the mouse, it shifts relative to the object.
Here is my input processing code. Input is a struct that contains booleans for all of the relevant input buttons and floats for mouse position.
void readSdlInput(Input* input) {
SDL_Event event;
while (SDL_PollEvent(&event) == 1) {
/* keyboard input handling */
}
SDL_MouseButtonFlags mouseButtons = SDL_GetMouseState(&input->mouseX, &input->mouseY);
/* mouse button handling */
}
I also attempted an alternative version by swapping out SDL_GetMouseState for SDL_GetGlobalMouseState because I figured maybe synchronous vs. asynchronous communication was somehow responsible for the error. This is what the input processing code looked like, though it seemingly had the same effect.
void readSdlInput(Input* input, SDL_Window* window) {
SDL_Event event;
while (SDL_PollEvent(&event) == 1) {
/* keyboard input handling */
}
float32 mouseXGlobal, mouseYGlobal;
int32 windowX, windowY;
SDL_GetWindowPosition(window, &windowX, &windowY);
SDL_MouseButtonFlags mouseButtons = SDL_GetGlobalMouseState(&mouseXGlobal, &mouseYGlobal);
/* mouse button handling */
}
And here is the code that handles movement of the object. When the object is initially grabbed by the cursor, it saves the offset between the cursor and object, and will continuously set the object position to maintain that offset each update.
void updateObjPos(const Input* input, State* state) {
/* determine if object was grabbed */
/* if object was just grabbed */
state->objOffsetX = input->mouseX - state->objX;
state->objOffsetY = input->mouseY - state->objY;
state->isObjHeld = true;
/* if object was already grabbed */
state->isObjHeld = true;
/* if object is not being grabbed at all */
state->isObjHeld = false;
if (state->isObjHeld) {
state->objX = input->mouseX - state->objOffsetX;
state->objY = input->mouseY - state->objOffsetY;
/* forcefully set objX and objY if they are out of bounds */
}
}
Both of the above functions are called each update step, with readSdlInput earlier, updateObjPos later, and all graphics last. Ideally, what I want is for the object to move exactly in lockstep with the cursor while being dragged, and I’m not sure how to achieve that.