PDA

View Full Version : Smooth continuous keyboard input and capturing multiple keys simultaneously



fiodis
11th December 2012, 02:02
I'm using the keyboard to navigate in an OpenGL scene. The problem is, when I hold down the "w" key to move forward, I edge forward a tiny bit first, pause, then glide forward smoothly. That's just how keyboard input works in Windows - when you hold down a key, there's a pause before it begins repeating. It's useful for, say, typing, but not much good for 3D navigation. Professional games override this somehow. I was wondering if there was a way to override this behavior with Qt, to eliminate this brief pause before the key starts repeating.

Also, in games you can for instance press "w" and "d" simultaneously to move diagonally forward and to the right. In Qt the way I have it set up now (just monitoring for key down events) I can only press one key at a time. So if I mashed "w" and "d" at the same time, one would trigger before the other, and I would move either forward or right, but not both. Is there some way I could work around that and detect when multiple keys are held down?

wysota
11th December 2012, 10:11
Intercept both keyPress and keyRelease events. In the keyPressEvent set a flag that a particular key is down, in keyReleaseEvent lower that flag. Then in your game loop (if you don't have one, just use a timer with a small period) simply check if the flag is raised or not and navigate your scene. Of course you will have to disable key repeating.

fiodis
11th December 2012, 20:35
Hmm, I never thought of it that way. It works perfectly, thanks! I guess I was hung up on the idea of somehow overriding the way Qt recieved keyboard events.

wysota
11th December 2012, 20:48
Hmm, I never thought of it that way. It works perfectly, thanks! I guess I was hung up on the idea of somehow overriding the way Qt recieved keyboard events.

Never rely in games on events being delivered in constant time spans or in moments when you expect them to be delivered (that especially counts for repainting). Always run a timer controlled loop. Only then you'll be certain how fast your game really "plays". And it's not enough to have a simple timer that triggers 10 times per second to be sure you get 10 game ticks per second. You'll get at most 10 ticks per second. What you should do is you should run a single shot timer and note the current time. When the timer fires, check the current time and calculate the difference from the last timeout. It might be that more than one tick has passed and also your next timeout may need to be adjusted because last tick might have used more time than you think.