Search code examples
clojureleiningenquil

Clojure Quil slow key input


Been learning some Clojure lately. Just making a simple game with the Quil library where I can move around using the arrow keys, but I ran into a minor (but annoying) problem -- when I hold down an arrow key, my character moves on the screen, but after the first slight movement, there's a delay until the character starts moving again. Once the character starts moving again, the movement is continuous with no problems. Basically what it feels like is that the key being held down isn't being registered by the program for almost a second after the first slight movement. This seems like such a tiny problem but it's very noticeable and annoying. Also I'd like to learn why this happens simply to learn.

By slight movement I mean the key press is instantly registered and the character moves a bit. Also if I keep tapping on the key fast, all the presses are instantly registered and the character moves as you'd expect. The problem only occurs when I hold the key down. Any ideas what could be causing this and how to fix it? Here's the sketch with the :key-pressed handler. Thanks.

(q/defsketch hello-quil
:title "Game"
:size [800 500]
; setup function called only once, during sketch initialization.
:setup setup
; update-state is called on each iteration before draw-state.
:update update-state
:draw draw-state
:key-pressed
(fn [state { :keys [key key-code] }]
(case key
  (:up) (if (> (state :p-left) 5) (assoc state :p-left (- (state :p-left) 15)) state)
  (:down) (if (< (state :p-left) 395) (assoc state :p-left (+ (state :p-left) 15)) state)
  state))
:features [:keep-on-top]
; This sketch uses functional-mode middleware.
; Check quil wiki for more info about middlewares and particularly
; fun-mode.
:middleware [m/fun-mode])

Solution

  • Don't rely on the key event being repeated for you when the key is held down. Use key-released and time in the update functions. Put key-down into your state, set it to true in key-pressed and to false in key-released, then update your character position in update-state when key-down is true.