lualove2d

how can i fix diagonal movement being faster than normal movement? (lua/love2d)


When I move diagonally, the movement becomes faster, I know why this happens I just dont know how to fix it.

function love.update(dt)
    if love.keyboard.isDown("w") then player.y = player.y - 75 * dt
    end
    if love.keyboard.isDown("s") then player.y = player.y + 75 * dt
    end 
    if love.keyboard.isDown("d") then player.x = player.x + 75 * dt
   end
    if love.keyboard.isDown("a") then player.x = player.x - 75 * dt
   end
end

Solution

  • The solution lies in some simple vector math. Let's calculate the dir to move in from the pressed keys:

    local d = {x = 0, y = 0} -- direction to move in
    if love.keyboard.isDown("w") then d.y = d.y - 1 end
    if love.keyboard.isDown("s") then d.y = d.y + 1 end
    if love.keyboard.isDown("d") then d.x = d.x + 1 end
    if love.keyboard.isDown("a") then d.x = d.x - 1 end
    

    Now, you might get a diagonal direction like {x = 1, y = 1} out of this. What's the length of this vector? By the Pythagorean theorem, it's sqrt(1² + 1²) = sqrt(2), roughly 1.4, not 1. If going "straight", you get just 1. Thus, you'll be going about sqrt(2) times faster if going diagonally.

    We can fix this by "normalizing" the direction vector: Keeping the direction, but setting the magnitude to 1. To do so, we just divide it by its length, if the length is larger than 0 (otherwise, just keep it as 0 - the player is not moving at all in that scenario):

    local length = math.sqrt(d.x^2 + d.y^2)
    if length > 0 then
        d.x = d.x / length
        d.y = d.y / length
    end
    

    now just scale this with the desired speed, and apply it:

    local speed = 75
    player.x = player.x + speed * d.x
    player.y = player.y + speed * d.y
    

    (Note: this gives you fractional x / y coordinates; I expect your drawing code to deal with those properly.)