What you need here is to stop using event driven programming methods. You need to switch to a more tradition game programming style.
You want to run a game loop that provides a steady pulse to your program. Each iteration of this loop you check the keyboard state. Use GetAsyncKeyState
for that. Check the state of each key that you are interested in. In your game loop you will also be driving any updates to the OpenGL canvas.
I can see from your update that you are already using GetAsyncKeyState
. But that really does not make a lot of sense when used in response to an OnKeyDown
event. Either you use event driven synchronous I/O, or polling asynchronous I/O. I cannot understand why you are trying to mix the two paradigms.
The way you call GetAsyncKeyState
looks wrong. You should write it like this:
function KeyPressed(nKey: Integer): Boolean;
begin
Result := GetAsyncKeyState(nKey) < 0;
end;
I also suggest that in each iteration of your main loop you call GetAsyncKeyState
once and once only for each key. Save the returned value to a local variable. That avoids the scenario where a key is deemed to be down at the start of the iteration, but then the same key is up at some later point in the iteration. That's an issue you need to be alive to with asynchronous I/O.