tehwalrus tehwalrus - 2 months ago 8x
Python Question

Pygame - first person shooter "look" with mouse

I am not writing a game but a scientific renderer using Pygame. I'd like the controls to work just like in a first-person shooter, so that a user can navigate using a familiar set of controls.

I have tried to write the code to have the same properties as the 'look' feature in e.g. Skyrim or Half-Life but the mouse doesn't move the cursor - it lets you look around and around, in infinite circles. Clicking should have no effect.

The first attempt for the controls:

(code inside a game loop)

delta_y, delta_x = pygame.mouse.get_rel()
rotation_direction.x = float(delta_x)
rotation_direction.y = float(delta_y)

(don't ask me why, but y and x need to be reversed like this to get the expected look directions; must be something to do with the camera transform implementation, which isn't mine.)

This, however, leads to a cursor sitting on top of the window, and when the cursor gets to the edge of the screen the window stops rotating; i.e. the code is reporting the actual position on the screen.

I tried to 'reset' the mouse position every game loop (and, incidentally, hide the mouse):

pygame.mouse.set_pos([150, 150])

But this generates a symmetrical 'move back to start' delta in the next loop, meaning that you couldn't 'look' anywhere.

To summarize, I want to:

  • detect actual mouse motion reported from the device

  • not move/show any OS cursor

  • not clip at the 'edge of a screen'

What is the best way to do this, using Pygame or other Python hacks?


http://www.pygame.org/docs/ref/mouse.html :

If the mouse cursor is hidden, and input is grabbed to the current display the mouse will enter a virtual input mode, where the relative movements of the mouse will never be stopped by the borders of the screen. See the functions pygame.mouse.set_visible - hide or show the mouse cursor and pygame.event.set_grab (docs) - control the sharing of input devices with other applications to get this configured.