big-bang
не «опрашивает клавиатуру», что является проблемой.Скорее, он вызывает ваш обработчик on-key
всякий раз, когда операционная система доставляет событие нажатия клавиши.Когда вы удерживаете клавишу на клавиатуре, операционная система будет отправлять множество событий нажатия клавиш в соответствии со скоростью, с которой вы настроили повторение клавиш на вашем компьютере, но это не то, от чего вы хотите зависетьдля чего-либо другого, кроме разрешения пользователю набирать текст.
Вместо того чтобы полагаться на скорость повторения ключа операционной системы (которая может сильно различаться между компьютерами или даже между пользователями одного компьютера), следите за тем, какиеклавиши в данный момент нажаты и используют эту информацию для обновления позиции персонажа игрока в обработчике on-tick
, который выполняется на надежных часах.Например, определите состояние мира следующим образом:
(struct world-state (player-posn keys))
(struct keys-state (up right down left))
(define initial-world (world-state initial-player-posn (keys-state #f #f #f #f)))
В своем обработчике on-key
обновите состояние мира, чтобы изменить соответствующую часть world-state-keys
на #t
, и добавьте соответствующий on-release
обработчик для изменения флага обратно на #f
при отпускании ключа.Затем вы можете вычислить текущую скорость игрока на основе набора нажатых клавиш:
(struct velocity (x y))
(define (key-state->magnitude v)
(if v 1 0))
(define (keys-state->velocity s)
(velocity (- (key-state->magnitude (keys-state-right s))
(key-state->magnitude (keys-state-left s)))
(- (key-state->magnitude (keys-state-up s))
(key-state->magnitude (keys-state-down s)))))
Вы можете использовать эту информацию в on-tick
, чтобы обновить позицию игрока с надежной скоростью, вместо того, чтобы полагаться на недетерминированныйповедение настроенной операционной системой частоты повторения ключей.