Day 023: INKEY$ - Printable Version +- QB64 Phoenix Edition (https://qb64phoenix.com/forum) +-- Forum: Official Links (https://qb64phoenix.com/forum/forumdisplay.php?fid=16) +--- Forum: Learning Resources and Archives (https://qb64phoenix.com/forum/forumdisplay.php?fid=13) +---- Forum: Keyword of the Day! (https://qb64phoenix.com/forum/forumdisplay.php?fid=49) +---- Thread: Day 023: INKEY$ (/showthread.php?tid=1229) |
Day 023: INKEY$ - Pete - 12-03-2022 INKEY$ is one of several methods to communicate with the keyboard. Others are _KEYHIT, _KEYDOWN, INP(), PEEK and POKE, and for Windows users, the function GetAsyncKeyState%. So why is INKEY$ so much better than those other choices, why because I code with it, of course! Well, my comedy bit aside, INKEY$ is comfortable for me because it has easily recognized key associations, by string representation of ASCII values. Terminate loop with the Esc key example... Code: (Select All) DO Since INKEY$ functions as a string, unlike the other alternatives, we need recognize a string is true or false by being either filled or null. Terminate loop with press almost any key... Code: (Select All) DO I find the best way to set up a keyboard poll routine is by assigning a variable to INKEY$... Code: (Select All) DO "...press almost any key." WTH is that??? Well, INKEY$ does not register for certain keys like... Shift Ctrl Alt Fn Windows key PrtScr NumLock Capslock These keys need to be referenced in some other either supportive method or via a different key recognition keyword like _KEYDOWN. An "old school" method I love, and successfully lobbied for 15+ years ago, is the supportive method of using PEEK addresses. This routine identifies if Alt, Ctrl, or Shift keys are held down while other keys are pressed... Code: (Select All) _CONTROLCHR OFF ' Allows us to key input combinations that would otherwise adversely affect screen output. Cool, right? Well, not so fast there Sparky, there is a drawback. We can only read 3 key inputs at a time. Hold Shift + Ctrl + Alt then press "A" and just like I stated, the 4th input, "A" won't get printed. INP() won't help here either, and interestingly enough, although _KEYHIT and _KEYDOWN can handle most 3 key combinations, I noted some arrow combos and others were not registered when trying to get that technique to work. WinAPI can recognize some but not all 4+ multiple key presses. Fool around with some keys in this example if you have a Windows System. Hold Shift+Ctrl+Alt and try some arrow keys etc to see which ones show up for INKEY$. Some will, some won't, but those are all 4 key press events with this INKEY$ helper. The only key I set to register in the alphabet is "A" so try Shift+Ctrl+Alt+A to see them all register. Oh, if you fooled with the code to try and get A+B+C+D to register, it would only register A+B+C. Code: (Select All) CONST VK_SHIFT = &H10 'SHIFT key So what else can we say about INKEY$? Well, it can be used in combination with other keyboard keywords. Maybe not good practice, but just saying it's workable. INKEY$ stores key presses in a buffer. You can use _KEYCLEAR to clear that buffer. Some programs need this to stop users who press keys during a program pause from being used in the routine. SLEEP is actually a very simple example... Code: (Select All) SLEEP A bit more involved example of the buffer uses a delay to slow the typing output to the screen. With the buffer, Demo 1, the output catches up after you are done fast typing. In demo 2, _KEYCLEAR clears the buffer and the utput stops the moment the user stops fast typing. Code: (Select All) PRINT "Demo 1: Buffer will catch up to your typing. Press Es when ready for demo 2..": PRINT On a final note, my beloved INKEY$, as stated previously, can't do everything. For instance say you want to use Ctrl + and Ctrl - to resize text, just like browsers. Well, we can't do that with INKEY$, but we can use _KEYHIT or Win32 API. An example of each is provided here: https://qb64phoenix.com/forum/showthread.php?tid=1230 Pete RE: Day 023: INKEY$ - mnrvovrfc - 12-03-2022 "INP(), PEEK and POKE", eh? "INKEY$" was always one of my favorite functions but with that keystroke buffer I considered a PITA. Without a buffer, however, say on the TRS-80 Color Computer, sometimes the computer was unresponsive thanks to the slow interpreter. Note that porting to other BASIC's could be a headache, such as Freebasic developers' decision to change to CHR$(255) from CHR$(0) the first out of two characters returned by arrow key or such other key. The CHR$(255) + "k" (lowercase "K") combination then could be used to trap the "X" on the right-hand corner of a window, for a program compiled in GUI mode. Despite attempts to phase out "INKEY$" this is a stronghold for beginners. A great many programs still use it and don't resort to "cheating" by looking at input ports and special memory areas. However, a game that has to look and act professionally such as an RPG requires extra strength interacting with HID. I have experienced this. I have to go look for the source code of a program that mimicked a good game I played on the Apple IIe. The response is a bit late because it uses "INKEY$" and also involved "_LIMIT" used inside a loop. This was already discussed sometime ago. I had created another game which could have produced laughter if I shared it here, because it was supposed to convey the sense of speed. Some spaceship travelling "forward" through space either slowly or quickly, through "obstacles". But it doesn't do it by scaling "_DELAY" and it doesn't use "_LIMIT". The way I did it, I think would cause someone to say, "This game was done by a n00b!" Actually it's a work in progress (was done in 32-bit Linux with Freebasic). |