Mouse: How to emulate "MouseLook" from FPS games?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Mouse: How to emulate "MouseLook" from FPS games?

Post by Jasoco »

This is a hard question to put into words so I hope that title didn't look stupid.

Anyway, of course I'm working on a Wolfenstein-style game engine and I want to implement mouse movement. i.e. "MouseLook" but I'm having a problem figuring out if it's possible to do well or at all in Löve.

I tried locking the mouse to the window, then constantly moving the mouse to the center of the window and checking if the mouse moves to the left or the right. Not having much luck making it work well at all.

Basically I need to figure out how to, not detect where on the screen the mouse is going, but what direction it is moving and how fast it is moving. Then use that to return the values I need for speed.

Currently I have this:

Code: Select all

  if love.mouse.getX() < oldMouseX then
    local sp = (oldMouseX - love.mouse.getX()) / 50
    if sp < -1 then sp = -1 end
    player.dir = -sp
  elseif love.mouse.getX() > oldMouseX then
    local sp = (love.mouse.getX() - oldMouseX) / 50
    if sp > 1 then sp = 1 end
    player.dir = sp
  else
    player.dir = 0
  end

  if love.mouse.getX() < 100 or love.mouse.getX() > windowWidth - 100 then
    love.mouse.setPosition(windowWidth / 2, windowHeight / 2)
  end

  oldMouseX = love.mouse.getX()
But it doesn't work as well as it should.
User avatar
thelinx
The Strongest
Posts: 857
Joined: Fri Sep 26, 2008 3:56 pm
Location: Sweden

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by thelinx »

Jasoco wrote: I tried locking the mouse to the window, then constantly moving the mouse to the center of the window and checking if the mouse moves to the left or the right. Not having much luck making it work well at all.
That's the classic way, and I remember doing that ages ago for a LÖVE raytracer. I'll try looking for it...

edit: Well, I found the post. But it turns out, that attachment was lost in the alien invasion way back when. Darn.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by Jasoco »

If anyone finds anything that works well let me know.
User avatar
ivan
Party member
Posts: 1912
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by ivan »

thelinx wrote:I tried locking the mouse to the window, then constantly moving the mouse to the center of the window and checking if the mouse moves to the left or the right.
That probably won't work very well especially in windowed mode.
If the user sweeps the mouse really fast and presses a button the Love window might lose focus.
The 'right' way might be to have an 'exclusive mode' for the mouse where the cursor is invisible and is locked to the window by the OS.
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by Boolsheet »

To get the latest position of the mouse you have to pump it in with love.event.pump. This means you also have to pump after you set a new position and expect getX to return it right afterwards.

A few things to consider:
LÖVE 0.7.2 pumps after love.draw and before love.graphics.present. Because present may wait for vsync (up to ~16 ms) you have the position of the mouse from some time ago in the next love.update call. You can force an update if you call love.event.pump yourself at the beginning of love.update. (0.8.0 will pump before love.update)

The default USB polling rate is 125 hz. A lot of movement can happen in 8 ms (or 16 if you stick to a framerate of 60 fps) and you only get where the mouse ended up at.
Shallow indentations.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by Jasoco »

ivan wrote:
thelinx wrote:I tried locking the mouse to the window, then constantly moving the mouse to the center of the window and checking if the mouse moves to the left or the right.
That probably won't work very well especially in windowed mode.
If the user sweeps the mouse really fast and presses a button the Love window might lose focus.
The 'right' way might be to have an 'exclusive mode' for the mouse where the cursor is invisible and is locked to the window by the OS.
No, "locking" the mouse to the window means the mouse can't leave the window. Losing focus isn't an issue.
Boolsheet wrote:To get the latest position of the mouse you have to pump it in with love.event.pump. This means you also have to pump after you set a new position and expect getX to return it right afterwards.

A few things to consider:
LÖVE 0.7.2 pumps after love.draw and before love.graphics.present. Because present may wait for vsync (up to ~16 ms) you have the position of the mouse from some time ago in the next love.update call. You can force an update if you call love.event.pump yourself at the beginning of love.update. (0.8.0 will pump before love.update)

The default USB polling rate is 125 hz. A lot of movement can happen in 8 ms (or 16 if you stick to a framerate of 60 fps) and you only get where the mouse ended up at.
That's confusing.
User avatar
MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by MarekkPie »

Jasoco wrote:That's confusing.
He's saying that the return values for any of the love.mouse methods won't give you the updated position until after draw is called. So, for instance, in your code:

Code: Select all

  if love.mouse.getX() < 100 or love.mouse.getX() > windowWidth - 100 then
    love.mouse.setPosition(windowWidth / 2, windowHeight / 2) -- even after this has changed...
  end

  oldMouseX = love.mouse.getX() -- this will still reflect the x-coordinate BEFORE setPosition()
Which could cause you to get some weird, inexplicable push back when you reach that boundary. Continuing on that mindset, the next time update() is called:

Code: Select all

  if love.mouse.getX() < oldMouseX then
    -- ...
oldMouseX would still be at whatever value it was at the end of the last call, even if it were outside the boundary. If you put:

Code: Select all

  if love.mouse.getX() < 100 or love.mouse.getX() > windowWidth - 100 then
    love.mouse.setPosition(windowWidth / 2, windowHeight / 2)
    love.event.pump() -- Eats all the events in queue immediately
  end

  oldMouseX = love.mouse.getX() -- Now the mouse position is correct
Then it should fix any pushback. Hopefully that clears that up. I've been trying to emulate that type of control (albeit "dragging" a ball on a 2d plane) and am having trouble getting the correct "feel." It might have a bit to do with some of the more technical stuff Boolsheet is talking about.
User avatar
richapple
Citizen
Posts: 65
Joined: Sun Dec 25, 2011 10:25 am

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by richapple »

I'm not sure, but aren't you looking for this: love.mouse.setGrab?
I don't know if it will work, but I found this from some old project and it works.
Here is forum link: Zombie baseball

No, wait. It uses more than just love.mouse.setGrab.
Here's love.load():

Code: Select all

  love.mouse.setGrab(true)
  love.mouse.setPosition(love.graphics.getWidth()/2, love.graphics.getHeight()/2) -- I'm not sure if it's needed
  love.mouse.setVisible(false)
love.update(dt):

Code: Select all

  m_diff_x = love.mouse.getX() - love.graphics.getWidth()/2
  m_diff_y = love.mouse.getY() - love.graphics.getHeight()/2

  love.mouse.setPosition(love.graphics.getWidth()/2, love.graphics.getHeight()/2)
Anyway, It's worth looking in source.
Last edited by richapple on Tue Jan 10, 2012 7:45 am, edited 1 time in total.
User avatar
MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by MarekkPie »

setGrab() literally doesn't allow the mouse to move beyond the screen. The mouse position doesn't reflect where the mouse "would" be if it weren't clamped, it's where the mouse is in relation to the LOVE game.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Mouse: How to emulate "MouseLook" from FPS games?

Post by Robin »

Why don't you reset the mouse each frame?

That way, you don't have to compare to the old position of the mouse, you can just compare to the centre of the screen. And you don't need love.even.pump either then.
Help us help you: attach a .love.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 1 guest