Quick answer: Pygame events delivering pre-warp mouse positions after pygame.mouse.set_pos()? Events in the queue were enqueued before the warp — flush or use post-warp pygame.mouse.get_pos().
FPS code recentering the mouse after read still sees the user’s old position next frame. Events queued during the frame carry the position from before the warp.
Drain After Warp
pygame.mouse.set_pos(cx, cy)
pygame.event.clear(pygame.MOUSEMOTION)Clear the MOUSEMOTION queue so the next frame starts clean. Subsequent events report deltas from the center.
Use Relative
Better: pygame.event.set_grab(True) + pygame.mouse.set_visible(False), read rel attribute on MOUSEMOTION events. The OS keeps the cursor centered automatically.
Get vs Event Position
pygame.mouse.get_pos() returns the live position; events report queued positions. For an immediate read, use get_pos.
Verifying
FPS camera tracks smoothly without ghost frames at the warp boundary.
“Warps don’t affect events already queued. Use rel or drain MOUSEMOTION after warping.”
Grabbed-relative input is the standard FPS pattern — warp + drain only when grab isn’t an option (e.g. windowed debugging).