Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
How to detect key press held down? — Gideros Forum

How to detect key press held down?

AmuseumAmuseum Member
edited July 2017 in General questions
Gideros Event.KEY_DOWN only triggers once per key press, and not if a key is held down.

How do you detect a key that is continuously held down?

Comments

  • Simply detect Event.KEY_UP
    If it triggered, then that means that the key is not held down anymore

    Likes: antix

    +1 -1 (+1 / -0 )Share on Facebook
  • what do you mean by 'simply'? in addition to KEY_DOWN? do i need variable to keep track of what key is held down? why isn't this basic function part of the main library?
  • keszeghkeszegh Member
    edited July 2017
    because gideros is event-based. just like there is no mousex value.
  • hgy29hgy29 Maintainer
    I suppose it could be added, ie: application:isKeyPressed(keycode) or something like that.

    Likes: antix, talis

    +1 -1 (+2 / -0 )Share on Facebook
  • @hgy29, this would be good also because last time you added modifiers only to mouse events and not to key events, so to know if it is ctrl-key or alt-ctr-key etc such an isKeyPressed function would come handy (meanwhile i keep i do this by keeping track of key_down/key_up events for ctrl, alt, shift, etc.).

    Likes: antix

    +1 -1 (+1 / -0 )Share on Facebook
  • KEY_UP is only part of the solution. You need to keep track of which keys are held down, and register EVENT_FRAME so that your callback can be continuously applied.

    Essentially KEY_UP and KEY_DOWN are only useful to set and unset the variables, while EVENT_FRAME will update the game state based on the keys being held. For that matter, better have this key handling done globally, then EVENT_FRAME can delegate and specify the sprites that need to updated.
  • @Amuseum, you do not need EVENT_FRAME to keep a table of values that is always uptodate with the information whether a key is pressed or not. just KEY_DOWN/KEY_UP is enough.

    of course if you update your sprites according to the state of the key, then this may be done in EVENT_FRAME but that depends on your game. surely if you want something done at each frame you need something like that, that's independent of key handling in my opinion.
  • hgy29hgy29 Maintainer
    I won't say the KEY_UP and KEY_DOWN are only useful to record key states, because you often need to know how many times a specific key has been pressed/released, or even just if it has been pressed (and maybe released just after) recently.

    Anyhow if one just need to know if a key is currently pressed (ex: left/right in a platformer game) to update the player position in an enter frame event, then yes it would be easier to just query current key state from gideros than having to listen for key presses and releases, as @Amuseum says.

    Likes: keszegh

    +1 -1 (+1 / -0 )Share on Facebook
  • antixantix Member
    edited July 2017
    I was intrigued by this so this morning I made a small class to manage key presses. You can register up and down events for individual keys and you can query their up/down state whenever you like too. Maybe it will work for you @Amuseum :)
    Keys = Core.class()
     
    function Keys:init()
     
      self.keys = {}
     
      stage:addEventListener(Event.KEY_DOWN, function(e) -- key down listener
        local keys = self.keys
        local k = keys[e.keyCode]
        if k then
          k.state = true -- set state down
          if k.onDown then k.onDown() end -- run callback
        else
          keys[e.Keycode] = {state = true} -- create if it does not exist
        end
      end)
     
      stage:addEventListener(Event.KEY_UP, function(e) -- key up listener
        local keys = self.keys
        local k = keys[e.keyCode]
        k.state = false -- set state up
        if k.onUp then k.onUp() end -- run callback
      end)
     
    end
     
    function Keys:registerDown(k, f) -- register key down callback
      local keys = self.keys
      if keys[k] then
        keys[k].onDown = f -- set callback
      else
        keys[k] = {state = false, onDown = f} -- create and set callback
      end
    end
     
    function Keys:registerUp(k, f) -- register key up callback
      local keys = self.keys
      if keys[k] then
        keys[k].onUp = f -- set callback
      else
        keys[k] = {state = false, onUp = f} -- create and set callback
      end
    end
     
    function Keys:state(k) -- return state of key
      local keys = self.keys
      if keys[k] then
        return keys[k].state -- return current state
      else
        keys[k] = {state = false} -- create
      end
      return false
    end
    And an example of using it..
    local keys = Keys.new()
     
    keys:registerDown(KeyCode.E, function()
      print("e is down <img class="emoji" src="https://forum.gideros.rocks/resources/emoji/frowning.png" title=":(" alt=":(" height="20" />")
    end)
     
    keys:registerUp(KeyCode.E, function()
      print("e is up <img class="emoji" src="https://forum.gideros.rocks/resources/emoji/smile.png" title=":)" alt=":)" height="20" />")
    end)
     
    local function onEnterFrame(e)
     
      if keys:state(KeyCode.A) then
        print("a held")
      end
     
    end
     
    stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)
    +1 -1 (+5 / -0 )Share on Facebook
Sign In or Register to comment.