Вот как работает типичный игровой цикл:
repeat forever:
read all pending events
if current time > last frame + frame time:
last frame = last frame + frame time
update game
redraw screen
Таймер, который должен срабатывать каждые 300 мс, но не работает, если пользователь затопляет игру событиями, может быть сломан таймер. Однако, если вы перерисовываете экран для каждого пользовательского события вместо перерисовки экрана после обработки всех ожидающих событий, проблема заключается в вашем коде.
Вот пример сломанной версии игрового цикла:
repeat forever:
read the next pending event
if current time > last frame + frame time:
last frame = last frame + frame time
update game
redraw screen
Он сломан, потому что слишком часто пытается перерисовать экран. Если игрок нажмет две клавиши одновременно, они будут разделены на разные кадры, что не нужно.
Вышеуказанные циклы предполагают, что вы хотите рисовать на экране как можно чаще. Это очень часто, но вы можете рисовать на экране реже. Ваш метод использования событий должен быть в порядке, если вы перехватываете все ожидающие события перед перерисовкой экрана.
P.S. НЕ используйте несколько потоков для решения этой проблемы. Это вызвало бы огромный беспорядок.