Flushing the keyboard buffer?

I’m relatively new to Xojo. I’ve searched the documentation and other forum conversations, and couldn’t find what I’m looking for.
I’m programming a game (Windows). When the user completes a level, a message pops up saying “LEVEL COMPLETE”. After a three-second pause, the next level appears.
Problem is, during that three seconds, any key pressed by the user is considered to be a move at the start of the next level. I don’t want that.
Is there a way to flush the keyboard buffer before starting the next level? I know a couple of tricks to do this in VB, but nothing in Xojo.
Appreciate any help, as the game is otherwise pretty good.

To suppress keyboard entry, simply return True in the KeyDown event.

Thanks, Michel. I tried your suggestion, but I still get the same thing.
Keep in mind I want to allow keyboard entry, but any key that’s pressed between the time a level is completed and the time the next level starts needs to be ignored or thrown out the window. What’s happening is that these key presses are being processed as the first moves of the next level.
I believe these key presses are going into the keyboard buffer, and when the game continues, they’re being accepted as input.
It seems to be just the last key stroke that it’s accepting, if that helps.

Sorry, on closer investigation, it actually accepts all keystrokes pressed between levels.

Maybe you need to rethink how your app handles the keystrokes to begin with.
Why are they queuing up while not during gameplay? That does’t seem right.
Do you have the same issue on the pause screen?

You raise an interesting point…
Perhaps it’s the way I do the pause while the “Level Complete” message is showing. As it is right now, I’m just counting ticks until three seconds passes, like this:
Window1.RoundMessage = true
j = ticks/60
loop until ticks/60 >= j + 3
window1.RoundMessage = False
RoundMessage is a Boolean that tells the Paint method to display the “Level Complete” message. I refresh the canvas to get the message to display instantly. Then I count ticks until 3 seconds passes, set RoundMessage to False, and load the next level.
Should I be doing something inside that loop that reads from the keyboard buffer while the message is displayed, so that it is empty at the start of the next level?

at the end of a level set a flag “levelInPlay”
and in the keydown handler simply check if that flag is true
if not return true and do NOTHING with the keystroke
if it is then do whatever is normal for when there is a level being played

That makes sense. I tried it and I’m still getting that issue, but I guess I’ll just have to fool around with it some more.


There are several options, depending on the structure of your game.
Sounds like currently the keyboard events pile up because they cannot be processed while you send your app in circles. Once the game is back into normal mode, the canvas recives all the events.

One way to avoid this would be a flag like Norman proposed, but not combined with a tight loop. Instead, use a timer to jump to your level start after 3 seconds (or a xojo.core.timer.calllater method call). This way the canvas events are not blocked and the keydowns can be disregarded.

Often it is much better for a game not to use keydown events but check Keyboard.AsyncKeydown in its game loop. Depends on the kind of your game.

Or you could use AddHandler/RemoveHandler to override your keydown event handler temporarily and call an empty method instead. But that’s a rather dirty approach. I personally would try to avoid the waiting loop. It eats up CPU cycles for no reason and can make your GUI unresponsive.

[quote=315180:@David Roddick]That makes sense. I tried it and I’m still getting that issue, but I guess I’ll just have to fool around with it some more.


David, it may be time to ask : WHERE are you getting these key types ?

You are apparently not placing the keydown/return true where it will actually do something.

Which control has the focus during the game ?

The beep suggests the window receives the keys. But it could be the canvas if that is where you draw.

I would start by attaching keydown to any possible place, then put this in there :

System.debuglog currentMethodName

Then run the game in the IDE, open the message pane (third icon at the bottom of the center pane), and start punching.

Once you know where the keys are received, return true in there.

If keydown events were firing, the keystrokes wouldn’t stack up, return true or no. The problem is he’s got some tight loop that prevents the keydown event from firing at all. Tight loops are a bad idea. If you’re just waiting in a loop, use a Timer instead. If you’re doing actual work, put it in a Thread.

[quote=315177:@David Roddick]Window1.RoundMessage = true
j = ticks/60
loop until ticks/60 >= j + 3
window1.RoundMessage = False

Use timer instead. Using a tight loop for timing things is so inadequate with event driven programming.

Tim is right : this freezes the entire application, including events.

In languages such as Xojo, if an event is not over, other events cannot take place.

Instead of the loop, launch a 3 seconds single timer with in the Action event, set RoundMessage to False, and load the next level. These will happen nicely after 3 seconds and the timer will turn off.

Thanks for the help, guys.
I’ve actually resolved the issue. I no longer have the character-move code in the keydown (or keyup) events. I’ve moved it to within the game timer. KeyDown sets a flag indicating which arrow key Is being pressed, KeyUp sets the flag to 0, similar to what Norman suggested. At the start of the level, the flag is set to 0, and no moves occur until the user presses a key.
Thanks again for the help. I’m a VB programmer making the transition to Xojo, so I’m going to be a little confused for a while. :slight_smile:

Use Keyboard.AsyncKeydown instead. It gives you the status of the key (pressed/not pressed) at the time you call it.