## Optimal way for wasd movement, no diagonals?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Eglaios
Prole
Posts: 36
Joined: Mon May 03, 2021 8:45 pm

### Optimal way for wasd movement, no diagonals?

I want to make a sprite move using wasd on a 2d environment, but without diagonals.

For this, I need more than a basic if-else due to priority : if I press "right" while "up" is already down, I'd want the sprite to go right, though depending on which keytest runs first, "right" is likely to be ignored, returning "up" instead, which is a problem.

So I thought about something like this :

Code: Select all

local last_direction
local directions = {"w","a","s","d"}

function love.keypressed(k)
for i, key in pairs(directions) do
if k == key then
last_direction = key
break
end
end
end

function love.update(dt)
if love.keyboard.isDown(directions) then
if love.keyboard.isDown(last_direction) then
move(last_direction)
else
--Test other keys in case last_direction got released while another one was still down
if love.keyboard.isDown("w") then
move("w")
end
--Run test for each other directions as well
end
end
end

function move(key)
--Move the sprite towards key's direction
end
Didn't verify the syntax, but it's pretty much about registering the last direction input so it gets priorized, this being followed by an if-else keytest in case the last key got released while another one was still down.

So would this be good enough for a non-diagonal 2d control? Would there be a better way? If not, could I change anything to improve this code?

Thanks once more to anyone who will take the time to answer!
Currently working on game music...
darkfrei
Party member
Posts: 417
Joined: Sat Feb 08, 2020 11:09 pm

### Re: Optimal way for wasd movement, no diagonals?

Normally it's enough to make something like:
if up then move_up()
elseif down then move_down()
elseif left then move_left()
elseif right then move_right()
else move_as_before() end
Falling in LÖVE
I Löve Lua and Love2D
pgimeno
Party member
Posts: 2819
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Optimal way for wasd movement, no diagonals?

That might work, though I'd be careful to clean last_direction when no movement key is pressed. It still favours one direction over the others when three keys are pressed and the direction key is released, though; to do it 100% right you'd need to add the movement keys to a table. But that's a minor thing.

Also, note that the position of WASD varies depending on the keyboard language. For example, the equivalent of WASD on French keyboards is ZQSD, and it's very difficult for a French to play a game with WASD controls. To avoid problems, always use the second argument of love.keypressed instead of the first, and isScancodeDown instead of isDown.

And better use ipairs instead of pairs in this case.
milon
Party member
Posts: 209
Joined: Thu Jan 18, 2018 9:14 pm

### Re: Optimal way for wasd movement, no diagonals?

Eglaios wrote: Sun Sep 12, 2021 9:07 pm I want to make a sprite move using wasd on a 2d environment, but without diagonals.

For this, I need more than a basic if-else due to priority : if I press "right" while "up" is already down, I'd want the sprite to go right, though depending on which keytest runs first, "right" is likely to be ignored, returning "up" instead, which is a problem.
I actually just posted a sample Love at https://love2d.org/forums/viewtopic.php?f=4&t=91962 for input handling. It reacts as you've requested - the latest input key takes precedence over the others, using love.keypressed(). If you're pressing Up and then press Right, the sprite will start moving Right. If you then release Right, the sprite will stop (you didn't re-press Up). I'm not sure if that's exactly the behavior you want or not, but it's a starter. It also doesn't use giant IF blocks for keyboard input. But it does use ugly IF blocks for handling swipe gestures for touch input - I'm new at that, lol.

EDIT - The movement is a little jerky because of using love.keypressed(). I don't code action games like platformers (so far) so it's irrelevant to me, but I believe this could be improved by setting a variable in the input handler (like keys.last maybe), and use love.update() to check if the key/scancode is still down (love.keyboard.isDown or love.keyboard.isScancodeDown).

### Who is online

Users browsing this forum: MrFariator and 47 guests