I was wondering what I should do in order to avoid input being dropped. Through testing, I realized that love.keyboard.isDown(key) would only return true if key was down when update() for that frame was running. Wanting to be able to get a true value even if a key is pressed and released quickly between updates, I tried love.keypressed(key) and love.keyreleased(key), but still had dropped input! I am assuming this is because, regardless of my order, they are both called before update(), so releasing the key would make the boolean for the key being pressed false before update() even ran.
Is there a commonly accepted way to avoid input drops?
Thank you.
Avoiding Dropped Input
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: Avoiding Dropped Input
If you want to know if a key was pressed since your last frame you should be setting the boolean flag to false in `update` not in `keyreleased`.
- substitute541
- Party member
- Posts: 484
- Joined: Fri Aug 24, 2012 9:04 am
- Location: Southern Leyte, Visayas, Philippines
- Contact:
Re: Avoiding Dropped Input
Also (this is just a quick idea,) you can use an action queue[1]. After each keypressed, append the queue with the actions caused by the key press: for example, <spacebar> => append table with action "jump", <uparrow> => append table with action "moveup" so on so forth. Actions can be functions, or string keys to another table which holds the functions.
Then at love.update, you just run the action queue in sequence and remove them (taking great care not to skip table indices.) Or you may not remove the actions as you go, and allow for reverse actions ala Braid
I'm just thinking out loud here, didn't actually use these ideas...
1. Making stuff up here, though I think that's what it's called...
Then at love.update, you just run the action queue in sequence and remove them (taking great care not to skip table indices.) Or you may not remove the actions as you go, and allow for reverse actions ala Braid
I'm just thinking out loud here, didn't actually use these ideas...
1. Making stuff up here, though I think that's what it's called...
Currently designing themes for WordPress.
Sometimes lurks around the forum.
Sometimes lurks around the forum.
Re: Avoiding Dropped Input
may I ask how you are testing this? All keyboard events should go through SDL, and all SDL events should go through the love keyboard handlers. And there cannot be a smaller update rate than the framestep because SDL events are only handled there (unless you replace the default love.run and do it yourself in some other way).Deldrith wrote:I was wondering what I should do in order to avoid input being dropped. Through testing, I realized that love.keyboard.isDown(key) would only return true if key was down when update() for that frame was running. Wanting to be able to get a true value even if a key is pressed and released quickly between updates, I tried love.keypressed(key) and love.keyreleased(key), but still had dropped input! I am assuming this is because, regardless of my order, they are both called before update(), so releasing the key would make the boolean for the key being pressed false before update() even ran.
Is there a commonly accepted way to avoid input drops?
Thank you.
- slime
- Solid Snayke
- Posts: 3162
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Avoiding Dropped Input
The OS will queue up multiple input events before love.event.pump puts them all into LÖVE's queue every frame. Then the default love.run calls love.event.poll in a loop until all events are processed, every frame. So it's definitely possible to press and release a key and have it cause a keypress and keyrelease event but not cause love.keyboard.isDown(key) to return true during a frame.s-ol wrote:may I ask how you are testing this? All keyboard events should go through SDL, and all SDL events should go through the love keyboard handlers. And there cannot be a smaller update rate than the framestep because SDL events are only handled there (unless you replace the default love.run and do it yourself in some other way).
Generally the way to avoid "dropped input" is to only use isDown for things that are logically "stuff happening over a duration of time", where pressing and releasing a key before even a single frame has been processed would have negligible effect on the game even if it could be handled using isDown.
You'd use love.keypressed and love.keyreleased (and mousepressed and mousereleased) for any action that should result in something happening immediately and not continuously.
Re: Avoiding Dropped Input
I guess I was a little unclear, by keyboars handlers I was only referring to keypressed and keyreleased.slime wrote:The OS will queue up multiple input events before love.event.pump puts them all into LÖVE's queue every frame. Then the default love.run calls love.event.poll in a loop until all events are processed, every frame. So it's definitely possible to press and release a key and have it cause a keypress and keyrelease event but not cause love.keyboard.isDown(key) to return true during a frame.s-ol wrote:may I ask how you are testing this? All keyboard events should go through SDL, and all SDL events should go through the love keyboard handlers. And there cannot be a smaller update rate than the framestep because SDL events are only handled there (unless you replace the default love.run and do it yourself in some other way).
Generally the way to avoid "dropped input" is to only use isDown for things that are logically "stuff happening over a duration of time", where pressing and releasing a key before even a single frame has been processed would have negligible effect on the game even if it could be handled using isDown.
You'd use love.keypressed and love.keyreleased (and mousepressed and mousereleased) for any action that should result in something happening immediately and not continuously.
If I understand OP correctly then he complains that keys don't show up there too?
Re: Avoiding Dropped Input
Tanner nailed it.
I moved it to love.draw because I needed the key press data in love.draw, but the idea is what Tanner said. This way, very quick key presses are not missed even if the frame duration is greater than the key press duration.
Edit: alternative way to clear them:
Edit 2: The problem is now to detect if the key was released and pressed again, as opposed to kept pressed. That needs extra logic in the game, but the necessary data can be obtained with love.keyreleased like this:
Code: Select all
local lk = love.keyboard
local pressed = {}
function love.keypressed(k)
if k == "up" or k == "down" or k == "left" or k == "right" then
pressed[k] = true
end
end
function love.update(dt)
-- use pressed.up etc here
end
function love.draw()
-- Simulate very intensive calculations
love.timer.sleep(0.1)
-- Display results
love.graphics.print(pressed.up and "UP pressed" or "UP not pressed")
-- Clear keypresses
if not lk.isDown("up") then pressed.up = nil end
if not lk.isDown("down") then pressed.down = nil end
if not lk.isDown("left") then pressed.left = nil end
if not lk.isDown("right") then pressed.right = nil end
end
Edit: alternative way to clear them:
Code: Select all
for k, _ in pairs(pressed) do if not lk.isDown(k) then pressed[k] = nil end end
Code: Select all
local pressed = {}
local released = {}
function love.keypressed(k)
if k == "up" or k == "down" or k == "left" or k == "right" then
pressed[k] = true
end
end
function love.keyreleased(k)
if k == "up" or k == "down" or k == "left" or k == "right" then
released[k] = true
end
end
function love.update(dt)
-- use pressed.up etc. here
-- use also released.up etc. to detect that they were released this frame
for k, _ in pairs(released) do pressed[k] = nil end
released = {}
end
Who is online
Users browsing this forum: Bing [Bot] and 2 guests