If you have anything useful to add, don't keep it to yourself =)
When you look in the source code of Löve, both love.keypressed() / keyreleased() as well as love.keyboard.isDown() are very fast functions, so the major difference between them isn't about performance, but rather how they force you to structure your program. This is because they represent different "questions" regarding keyboard input.
- The love.keyboard.isDown() function is a test that asks "is (this key) pressed right now?", so it tests for a specific key. When you use it inside love.update() for example, your program is asking per frame "is it pressed? is it pressed? is it pressed?...".
- The love.keypressed() / keyreleased() handlers ask (or rather, tell) that "(this key) has been pressed/released right now", and they run for all keys, differently than isDown() that tests for a specific key. These handlers are only executed when the press or the release happen, and not any other moment.
love.keyboard.isDown()
It can only tell you if a key is pressed or not. It cannot tell you when that key started being pressed, or when it was released.
If you wanted to know when a key was pressed then you'd have to use a variable to keep track of the state of the key on the previous frame so you can know when there's a change:
Code: Select all
local wasSpacePressed = false
function love.update(dt)
if love.keyboard.isDown('space') then
if wasSpacePressed then
-- Space was already pressed on the previous frame.
else
-- Space was *not* pressed on the previous frame, so do whatever you want to do
-- when space *begins* being pressed, and mark it as being pressed from now on.
-- (...)
wasSpacePressed = true
end
else
if wasSpacePressed then
-- Space *stopped* being pressed. Do what you need to do when space stops being pressed.
end
wasSpacePressed = false
end
end
Code: Select all
-- A table of 'keyData' tables.
-- Each 'keyData' table has the form {keyName, keyHandler}, where 'keyName' is the
-- string name of the key and 'keyHandler' is a function for reacting to that key.
local customizableKeys = {}
function love.update(dt)
for index = 1, #customizableKeys do
local keyData = customizableKeys[index]
local keyName, keyHandler = keyData[1], keyData[2]
if love.keyboard.isDown(keyName) then
keyHandler(dt)
end
end
end
That 'customizableKeys' table can be built out of data stored in something like a save file that has the keyboard mappings that the user configured on your game settings screen.
love.keypressed() / keyreleased()
They can only tell you when the key was released or pressed, so they work great for things that happen immediately, like ending the program. From the Löve wiki:
Code: Select all
function love.keypressed(key)
if key == 'esc' then
love.event.quit()
end
end
Although you could use all of keypressed() / keyreleased() / isDown() together, I think using some sort of temporary handler system would work better: when the key is pressed, you "activate" a handler, and in love.update() you execute all active handlers, and when the key is released you "deactivate" its handler:
Code: Select all
local allKeyHandlers = {}
-- Fill the 'allKeyHandlers' table with keyHandler objects.
-- (...)
local activeKeyHandlers = {}
function love.keypressed(key)
local keyHandler = allKeyHandlers[key]
-- See if there's a key handler for the key being pressed.
-- That is, if your game is listening to that key or not.
if keyHandler then
keyHandler:start()
activeKeyHandlers[key] = keyHandler
end
end
function love.update(dt)
for key, keyHandler in pairs(activeKeyHandlers) do
keyHandler:continue(dt)
end
end
function love.keyreleased(key)
local keyHandler = allKeyHandlers[key]
if keyHandler then
keyHandler:stop()
activeKeyHandlers[key] = nil
end
end
If you just need to know if a key is being pressed or not for the current frame then love.keyboard.isDown() is the simplest and easiest method. It can also be used in a way that supports customizable keys (you store the key name, whatever it is, in a variable, and use it with isDown()).
However, if your game needs to react to the three possible states of a key (the start of the key press, the continuation of that key press, and the release of that key press), then you'll end up writing less code if you use keypressed() / keyreleased() with some sort of handler system like explained above. If your game has lots of relevant keys, your code will also be slightly more performant (but not in a noticeable way) than testing for all relevant keys, for every frame, like you would if you were only using isDown().