What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Yolwoocle
Prole
Posts: 12
Joined: Sun Jan 16, 2022 11:12 am
Contact:

What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by Yolwoocle »

Hi.
I come from a background of making games on PICO-8, and its API has two functions, called "btn" and "btnp", which respectively return whether a button is down or if it's just been pressed (i.e. for the first frame). I have used myself to think about input in terms of checking it in the "update" function. However, LÖVE seems to have a "love.keypressed" function, which is, as far as I know, the only way to check if a button has been just been pressed (as opposed to checking if it's down continuously).
Imagine I have a game with different weapons, some of which are automatic, where you have to hold the "fire" button to fire, while others are manual, where you have to press on this button repeatedly to fire.
What is a helpful way to think about this? Use "love.keyboard.isDown" in my player's update method, and have separate code for "love.keypressed"? Seems weird to me that the same action should be put in different places in the code.
Thanks
Last edited by Yolwoocle on Sun Feb 27, 2022 8:15 am, edited 1 time in total.
MrFariator
Party member
Posts: 548
Joined: Wed Oct 05, 2016 11:53 am

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by MrFariator »

Personally, I use love.keypressed for any actual in-game utility, and love.keyboard.isDown for any debug/development cheats or tools. Generally, my player code doesn't check the inputs, but rather uses the observer pattern to receive inputs: the input handling code grabs the currently pressed/held/released keys, and sends out signals to any objects that may have an active listener. In this way, they are pretty agnostic as to where the inputs are coming from. Enables easy way to do something like input playback from replay files or similar.

For some small menus, however, where it would be more bothersome to activate/deactivate listeners, they use simple "isGameButtonXPressed/Down/Released" query functions, that simply check the stuff the input handler is keeping track of.
User avatar
BrotSagtMist
Party member
Posts: 657
Joined: Fri Aug 06, 2021 10:30 pm

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by BrotSagtMist »

I am using this code:

Code: Select all

love.keypressed= function( k )
 if KL[k] then KD[KL[k]]= 1 end
end
love.keyreleased= function( k )
 if KL[k] then KD[KL[k]]= nil end
end
Which looks easy enough but changes the way you do buttons quite dramatically.
First you get a layer to define your own keybinding:

Code: Select all

KL.up="up"
KL.w="up"
KL.space="fire"
will set booth w and the arrow key to be up, nice for arcade games. I do that in a config file.
Next you use it like

Code: Select all

if KD.up then 
 x=x+speed*KD.up*dt  
end
if KD.fire then 
 blah()
 KD.fire=nil
end
The lookup in a table is way cooler than using keyboard.isDown() and by niling the value after checking for it we can decide if we want to use it for continuous motions like a move or a single shot.
And since KD.up is a number value we can add analog joysticks instantly.
Even more we could also decrease the value as part of the physics, say for jumping so that

Code: Select all

KD.up= KD.up-dt
will give you a nice 1 second jump phase.
obey
User avatar
nehu
Prole
Posts: 11
Joined: Fri Feb 25, 2022 1:12 am
Location: Argentina, Maybe under your bed

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by nehu »

if you want to use something similar to the love.keypressed in love.update, you could use something like this:

Code: Select all

local keyPress = '' --sets the variable keyPress to an empty string

function love.update(dt)

    if keyPress == 'a' then --uses the keyPress var to detect the key that just got pressed
        
        print('fire')

    end

    keyPress = ''  --sets the keyPress to '' at the end of the code, so it only detects just when a key is pressed

end

function love.keypressed(key)

    keyPress = key --sets the keyPress to the key you just pressed
    
end
this basically makes a variable that stores the key you pressed and in the end of the love.update function it sets that var to '' (empty string)
so you just need to do something like:

Code: Select all

if keyPress == 'w' then
	--insert code
end
this should be less annoying than having to split your code in love.update and love.keyboardpressed :) !

and also you dont need to make a list of the keys you will use :P

Code: Select all

for i, v in pairs(problems) do
	fix(v)
end
User avatar
BrotSagtMist
Party member
Posts: 657
Joined: Fri Aug 06, 2021 10:30 pm

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by BrotSagtMist »

@nehu, your code will fail for more than one button because two at the same frame will overwrite each other.

If you want to have a cleaner access to isKeydown() you can simply wrap this around, for example using metatables:

Code: Select all

K= setmetatable({},{__index=function(_,k) return(love.keyboard.isDown(k))  end})
KP={}
KS= setmetatable({},{__index=function(_,k,r) r=KP[k] KP[k]= K[k] return not r and K[k] or false end})

love.draw=function()
 if K.space then  print("pressed") end --continious check
 if KS.a then  print("fire") end --one time check
end
But thats rather complicating stuff.
nehu wrote: Sun Feb 27, 2022 4:05 pm and also you dont need to make a list of the keys you will use :P
Note that a keylist is a big plus to have. I cant even play games on my computer without that since i do not have a qwerty keyboard. Such list is vital for configuring and it will bite you in the ass later if you want to add joypad or multiplayer modes and have no abstraction layer for the key input.
obey
User avatar
zorg
Party member
Posts: 3465
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by zorg »

BrotSagtMist wrote: Mon Feb 28, 2022 4:13 amI cant even play games on my computer without that since i do not have a qwerty keyboard.
Time for the daily reminder that keyconstants are useless and one should use Scancodes instead since those are irrespective of keyboard layout.

Code: Select all

local keys = {}

function love.keypressed(k,s)
  keys[s] = 0
end

function love.keyreleased(k,s)
  keys[s] = false
end

function love.update(dt)
  for k,v in pairs(keys) do
    if love.keyboard.isScancodeDown(k) then
      keys[k] = keys[k] + 1 -- or + dt if you want time elapsed in seconds and not frames.
    end
  end
end
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
BrotSagtMist
Party member
Posts: 657
Joined: Fri Aug 06, 2021 10:30 pm

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by BrotSagtMist »

Then youll end up with a situation that the documentation wont match.
"press x"
"where the heck is x?"
Edit: also forgot that in the custom keyboard scene scanncodes are altered too on the hardware site.
obey
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by ReFreezed »

zorg wrote: Mon Feb 28, 2022 4:28 am keyconstants are useless and one should use Scancodes
Only for controls. For keyboard shortcuts (like e.g. Ctrl+C to copy) keyconstants ought to be used.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
Yolwoocle
Prole
Posts: 12
Joined: Sun Jan 16, 2022 11:12 am
Contact:

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by Yolwoocle »

BrotSagtMist wrote: Mon Feb 28, 2022 4:36 am Then youll end up with a situation that the documentation wont match.
"press x"
"where the heck is x?"
Edit: also forgot that in the custom keyboard scene scanncodes are altered too on the hardware site.
Isn't there love.keyboard.getKeyFromScancode for this very purpose? Scancodes are great for people like me who use a French keyboard layout :P
MrFariator
Party member
Posts: 548
Joined: Wed Oct 05, 2016 11:53 am

Re: What is a helpful way to think about input? love.keypressed or love.keyboard.isDown?

Post by MrFariator »

Yeah, when you load the controls configurations, use love.keyboard.getKeyFromScancode to find out where they physically end up on the user's keyboard, and then display the appropriate character to the player in UI if necessary. This can be a bit of a headache to implement at first, but it's well worth it so that players don't complain about the default controls. A game having three action buttons at ZXC or ASD (on a qwerty keyboard layout) is relatively common in small indie games, but these don't make sense on a French keyboard, for instance.

I'm sure there may still be some edge-cases, but so long you give players the ability to rebind keys, many of those issues can be fixed.
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests