Using keycode detection
BlitzMax Forums/BlitzMax Beginners Area/Using keycode detection
| ||
I was learning about keycode detection and discovered that the way it is being used in this code snippet causes unexpected behavior.Strict Graphics 640,480 HideMouse Repeat Cls If KeyHit(key_return)=False DrawText "Return key for action -",100,240 DrawText "Escape key to exit.",100,255 If KeyHit(key_return) '<- This works after a few taps but KeyDown(key_return) works very well. Cls SetColor 0,255,0 DrawText "Return Key hit, now going to TheLoop().",100,240 Flip Delay 1700 TheLoop() EndIf EndIf Flip Until KeyHit(key_escape) Function TheLoop() Local x, x1 Repeat For x=30 To 200 If KeyHit(key_space) Return Cls SetColor -x,-x,255 DrawOval x,x,x,x SetColor 255,255,255 DrawText"Hit space key to get back to main loop",x,x+x Flip Next For x1=x To 30 Step-3 If KeyHit(key_space) Return Cls SetColor 255,-x1,-x1 DrawOval x1,x1,x1,x1 SetColor 255,255,255 DrawText"Hit space key to get back to main loop",x1,x1+x1 Flip Next Until KeyHit(key_space) End Function Of course I will avoid using keycodes in this way but was curious as to why it works badly. |
| ||
This works better:Repeat Cls local ReturnKeyHit = KeyHit(key_return) ' Get status of the return key once per loop If ReturnKeyHit=False ' Check the status of the return key (has it been pressed?) DrawText "Return key for action -",100,240 DrawText "Escape key to exit.",100,255 EndIf If ReturnKeyHit ' Check the key again Cls SetColor 0,255,0 DrawText "Return Key hit, now going to TheLoop().",100,240 Flip Delay 1700 TheLoop() EndIf Flip Until KeyHit(key_escape) When you call KeyHit, it retrieves the status of the given key and flushes the status of that key afterwards, to avoid problems. See this: Imagine you're writing a program that prints one line, every time you press the spacebar. If the key wouldn't get flushed after checking it's status, then after one hit on that key, your program would run forever, without you pressing any keys. Graphics 640, 480, 0 Start = MilliSecs() Repeat If KeyHit(key_space) Print "You pressed the spacebar" 'Prints in the IDE's output window endif Until MilliSecs() > (Start + 5000) Take this example. It runs for 5 seconds. If you press the spacebar, it would print the given statement. If you press again, it will print another statement. If the keyboard matrix wasn't flushed (only the status of the spacebar key will be flushed when using keyhit(key_space)), it would print the statement until the program ends (after 5 seconds after startup). To be able to use your loop, you'll have to press the return key twice in a loop, because you're checking it's status twice in one loop. I couldn't get your example to work on my system, because the loop was running faster than I could press the return key twice. Now this new loop stores the status of your return key in a variable and then it checks this variable for getting the status of the return key per loop. |
| ||
Thanks PowerPC603 - Thats why my code works if you rapidly tap the return key because the keyboard matrix receives the second keyhit during the time it took to draw the two lines of text. The code checks the If statements once per repeat/until sequence. In your example: As long as the KeyHit remains False the 1st If gets processed. When Keyhit is True only the 2nd If gets processed. AhHa Yea Much Better! |
| ||
Thats why my code works if you rapidly tap the return key because the keyboard matrix receives the second keyhit during the time it took to draw the two lines of text. You could get lucky if you pressed the spacebar only once, but during the drawing of the two lines of text. I saw this approach (using a variable for keyhit) in a topic for B3D a long time ago, they had the same problem. |