Search code examples
keyboarddartkeypress

How to listen to key press repetitively in Dart for games?


I know that you can listen to key press and down events with Dart like:

var el = query('#el');
el.on.keyDown.add((e) {});

But the problem here is that it fires only once. I want repetition.

So, I tried keyPress instead, but it has a slight delay before the repetition. I am working on a game and I want it to fire instantly and repetitively.


Solution

  • First of all, don't listen to keyPress events, because the "initial delay" depends on the operating system configuration! In fact, keyPress events may not even fire repetitively.

    What you need to do is to listen to keyDown and keyUp events. You can make a helper for this.

    class Keyboard {
      HashMap<int, int> _keys = new HashMap<int, int>();
    
      Keyboard() {
        window.onKeyDown.listen((KeyboardEvent e) {
          // If the key is not set yet, set it with a timestamp.
          if (!_keys.containsKey(e.keyCode))
            _keys[e.keyCode] = e.timeStamp;
        });
    
        window.onKeyUp.listen((KeyboardEvent e) {
          _keys.remove(e.keyCode);
        });
      }
    
      /**
       * Check if the given key code is pressed. You should use the [KeyCode] class.
       */
      isPressed(int keyCode) => _keys.containsKey(keyCode);
    }
    

    Then depending on what you do in your game, you probably have "a game loop" of some sort, in your update() method that gets called in every once in a while:

    class Game {
      Keyboard keyboard;
    
      Game() {
        keyboard = new Keyboard();
    
        window.requestAnimationFrame(update);
      }
    
      update(e) {
        if (keyboard.isPressed(KeyCode.A))
          print('A is pressed!');
    
        window.requestAnimationFrame(update);
      }
    }
    

    Now your game loop checks repetitively for A key pressing.