Issue #470 resolved
created an issue

(Possibly related to #74 and/or #399)

I'm working on a project that I would like to use FPS-style controls, i.e. continuous mouse movement in any direction. The traditional solution to this in SDL is to grab input and hide the cursor (respectively setGrab and setVisible in LOVE) - but LOVE doesn't have a way to get relative mouse motion, and the (invisible) cursor stops when it reaches the edge of the window, so taking deltas is out of the question as well.

Mouse motion events have already been ruled out I see, but it would be nice to at least have a "getRelativePosition" function, with the caveat that it should only be called once per frame.

This is personally a "blocker" issue for me right now, but I realize in the grand scheme of things it's pretty minor...

Comments (5)

  1. Boolsheet

    I don't have anything regarding the issue itself, but if you consider this a blocker, I can suggest a workaround. The mouse movement still only goes to the window edge and if you expect large movements it probably will feel weird to the player.

    local x, y = 0, 0
    function love.update(dt)
    	local mx, my = love.mouse.getPosition()
    	love.mouse.setPosition(400, 300)
    	x, y = x + (mx - 400)*0.2, y + (my - 300)*0.2
    function love.draw()
    	q:setViewport(-x, -y, 2000, 2000), q, 0, 0)
    function love.keypressed(k)
    	if k == "escape" then
    function love.load()
    	local imgData = love.image.newImageData(64, 64)
    	for x = 0, 63 do
    		imgData:setPixel(x, 0, 255, 255, 255, 255)
    		imgData:setPixel(0, x, 255, 255, 255, 255)
    	img =
    	img:setWrap("repeat", "repeat")
    	q =, 0, 1000, 1000, img:getWidth(), img:getHeight())

    Does this work for you? I didnt' make the cursor invisible, it should work even better then.

  2. criptych reporter

    Thanks for the suggestion. Long-term, it's not ideal (then again, I'm a perfectionist), but I think this'll work for what I need. Maybe I'm just too used to SDL_GetRelativeMouseState.

    P.S. It seems to work just fine whether the cursor is visible or not. The main difference seems to be that you don't need to setGrab(true).

  3. Alex Szpakowski

    Added new event callback love.mousemoved(x, y, xrel, yrel), where xrel and yrel are the amount of pixels moved since the last event. Added love.mouse.setRelative(bool relative) and love.mouse.isRelative. Resolves issue #470.

    Enabling relative mouse mode will hide the cursor and let the system generate relative mouse move events while preventing the mouse from getting stuck at the edges of the screen (i.e. you can keep moving the mouse in one direction forever and the relative movement events will be generated accordingly.)

    The reported absolute mouse position is not updated while relative mode is enabled, even while relative movement events are generated.

    → <<cset 9630f30311d9>>

  4. Log in to comment