Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:13 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MMBasic - When Does INKEY$ get reset to ""?

Author Message
Andrew_G
Guru

Joined: 18/10/2016
Location: Australia
Posts: 871
Posted: 01:06am 24 Aug 2020
Copy link to clipboard 
Print this post

Hi,
Firstly I can work around this "feature" with KEYDOWN but I'm trying to understand when INKEY$ is reset.

If I have:

. . .
Do: Loop While INKEY$ = ""  '1st Do Loop

'Print INKEY$;

Do                          '2nd Do Loop
 something
Loop While INKEY$ = ""

something else
...

MMBasic (at least on my CMM2) skips through the second Do Loop as though it has remembered the first INKEY$. Shouldnt it be reset at the begining of the second Do loop?
BUT if I insert something that requires an evaluation of INKEY$, like a Print statement, it works fine.

Cheers,

Andrew
(Im using CMM2 5.05.05b19)
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 03:05am 24 Aug 2020
Copy link to clipboard 
Print this post

INKEY$ removes the next character from the console input queue and returns it.  If there is nothing there it returns an empty string.  Whenever you use INKEY$ (even in a conditional test) you will remove the next character from the queue.

Normally you would use it like this:
DO
 s$ = INKEY$
WHILE s$ = ""

PRINT s$


Geoff
Geoff Graham - http://geoffg.net
 
Andrew_G
Guru

Joined: 18/10/2016
Location: Australia
Posts: 871
Posted: 03:23am 24 Aug 2020
Copy link to clipboard 
Print this post

Thanks Geoff.
I DO normally use a variable (eg S$) but for some reason I didn't this time.
Your explanation helps tremendously.

Cheers,

Andrew
 
Andrew_G
Guru

Joined: 18/10/2016
Location: Australia
Posts: 871
Posted: 03:45am 24 Aug 2020
Copy link to clipboard 
Print this post

Hi again Geoff,
If I use the following and if I hit ENTER for each anykey this fails too (ie it just Texts the first "1" in the second loop and then ends - any other key works.
Is that what you would expect?

Andrew

{Just thinking after I posted this, is ENTER treated as CR & LF ie as two characters? Then the second character makes T$ not "" so it passes through??}



 'INKEY$-Play.BAS
 ' Seeks to resolve odd Inkey$ behaviour
 dim integer I = 0
 cls
   
 do          '1st Do loop
   S$ = Inkey$
   I = I + 1
   Text 0, 100, "Press a key to move on " + Str$(I), "LB",2,1 ,RGB(green)
   Pause 500   'Just to slow it down
 loop while S$ = ""

 'S$ = ""
 I = 0
 do          '2nd Do loop
   T$ = Inkey$ 'Changed to T$ incase repeat of S$ was a problem
   I = I + 1
   text 0, 300, "Press a key to end " + str$(I), "LB", 2, 1, RGB(Cyan)
   pause 500   'Just to slow it down
 loop while T$ = ""

End

Edited 2020-08-24 13:50 by Andrew_G
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 04:14am 24 Aug 2020
Copy link to clipboard 
Print this post

I tend to flush the keyboard buffer after using INKEY$ if extra stray keys are a problem.

do
   i$ = inkey$
 loop until i$<>""

 DO : LOOP UNTIL INKEY$ = ""
 select case i$
...


Jim
VK7JH
MMedit
 
Andrew_G
Guru

Joined: 18/10/2016
Location: Australia
Posts: 871
Posted: 04:27am 24 Aug 2020
Copy link to clipboard 
Print this post

Thanks Jim,
That would do it!
Is this tip worth putting in a manual or something??

Cheers,

Andrew

(KEYDOWN works but is a little more involved)
 
shaputer
Newbie

Joined: 25/07/2020
Location: United States
Posts: 38
Posted: 01:14pm 24 Aug 2020
Copy link to clipboard 
Print this post

Could you elaborate on the KEYDOWN command ?  I was trying to figure out what was the best way to move a sprite when I press the arrow keys.

I get it to work with KEYDOWN, but in will only go in each direction ONCE.  I can't go RIGHT over and over.  The LOOP seems to be ignored even if I hold the KEY down without letting it go.

I couldn't get any movement at all using the INKEY$ command.

Thanks for any help.  
If what you are doing is bringing out the worst in you than stop doing it.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 01:26pm 24 Aug 2020
Copy link to clipboard 
Print this post

  Quote  Could you elaborate on the KEYDOWN command ?


Have a play with the attached. Over the top but gives you an idea of one approach

option explicit
option default integer
dim pressed(3)
settick 25,keyint
dim i
do
for i=0 to 3
  if pressed(i) then
    text i*mm.info(fontwidth),10, chr$(pressed(i))
  else
    text i*mm.info(fontwidth),10, chr$(32)
  endif
next i
loop

'routine to monitor keypresses and maintain a list of up to
'four  that are pressed at any one time
sub keyint
local i,j
local clearkey
local keys(7)
' take a local copy of the keydown function
for i=0 to 4
  keys(i)=keydown(i)
next i
if keys(0) > 4 then keys(0)=4 'limit of 4 keys can be pressed

' first clear any keys that were pressed that are no longer
for i=0 to 3
  clearkey=1
  if pressed(i) then
    for j=1 to keys(0)
      if keys(j)=pressed(i) then
        clearkey=0 'still pressed so don't clear
        keys(j)=0 'remove the key so it isn't used as a new press
      endif
    next j
  endif
  if clearkey then
    pressed(i)=0
  endif
next i
' now establish if there are any new key pressed
for i=0 to 3
  if pressed(i) then continue for 'slot already used
  for j=1 to keys(0)
    if keys(j) then
      pressed(i)=keys(j)
      keys(j)=0 'make sure a key isn't processed twice
    endif
  next j
next i
end sub
 
Andrew_G
Guru

Joined: 18/10/2016
Location: Australia
Posts: 871
Posted: 10:57pm 24 Aug 2020
Copy link to clipboard 
Print this post

Shaputer,
G'day and welcome.
I most definitely defer to Peter's far more comprehensive code above but this is what I adapted for version 2v6 of LunarLander here.
It has a number of limitations but it works for me.
I'd suggest having a play with Jim's tweak of INKEY$ above too.

Cheers,

Andrew

 'KEYDOWN Play.BAS
 '
 'Plays with the use of KEYDOWN
 
 Dim Integer I
 
 cls
 print "Press left, right, space or ESCAPE key"
 'MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM - Start of main loop
 do
   ' test for keypresses
   if keydown(0) then    'At least 1 key pressed
     IF TIMER > 200 THEN  'EXPERIMENTAL Not essential but change to alter response to subsequent key presses
       TIMER = 0
       'print Keydown(0); "  ";    'KEYDOWN(0) is the number of keys pressed
       for I = 1 to keydown(0)    'Only interested in 1 and above
         'print Keydown(0); "  ";keydown(i);"  ";
         'See Appendix F of manual for codes
         if keydown(I) = 27 then Exit Do     'ESCAPE so bail out
         if keydown(I) = 130 then GoLeft     'Left
         if keydown(I) = 131 then GoRight    'Right
         if keydown(I) = 32  Then GoSpace    'Space bar
         ' . . .
       next I
     endif
   End If
 Loop
 'mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm - end of main loop
 Print "Goodbye"
End
 
Sub GoLeft
 print "Left"
End Sub
 
Sub GoRight
 print "Right"
End Sub
 
Sub GoSpace
 print "Space"
End Sub
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 03:03am 25 Aug 2020
Copy link to clipboard 
Print this post

  shaputer said  Could you elaborate on the KEYDOWN command ?  I was trying to figure out what was the best way to move a sprite when I press the arrow keys.

I get it to work with KEYDOWN, but in will only go in each direction ONCE.  I can't go RIGHT over and over.  The LOOP seems to be ignored even if I hold the KEY down without letting it go.

I couldn't get any movement at all using the INKEY$ command.

Thanks for any help.  


INKEY$ works on both the USB keyboard and any attached terminal.

Using INKEY$, you have to be aware that what gets sent when the Enter key is pressed will depend on a user OPTION for the USB keyboard and Terminal program settings on the PC console.

KEYDOWN only works on the USB keyboard so it's use would exclude any user who is using their PC rather than a USB keyboard.

If you are not interested in multiple keys down at once, INKEY$ is easier to handle.
If you are likely to be interested in SHIFT-Arrow or Ctrl-Arrow etc, then KEYDOWN is required.

Jim
VK7JH
MMedit
 
shaputer
Newbie

Joined: 25/07/2020
Location: United States
Posts: 38
Posted: 02:23pm 25 Aug 2020
Copy link to clipboard 
Print this post

Thanks Everyone !    
If what you are doing is bringing out the worst in you than stop doing it.
 
shaputer
Newbie

Joined: 25/07/2020
Location: United States
Posts: 38
Posted: 12:29pm 26 Aug 2020
Copy link to clipboard 
Print this post

Well, I would never connect the CMM2 to a PC.  It defeats the purpose in my opinion.  I write and edit all programs directly using the keyboard connected to CMM2 that's connected to a monitor.

I have no interest in using more than one key to trigger the sprite. The arrow keys.
Keydown works perfectly, but the sprite still only moves once.  I will have to work on how to manipulate sprites.  Thanks, again everyone
If what you are doing is bringing out the worst in you than stop doing it.
 
Andrew_G
Guru

Joined: 18/10/2016
Location: Australia
Posts: 871
Posted: 11:20pm 26 Aug 2020
Copy link to clipboard 
Print this post

Hi Shaputer,
This is now my standard INKEY$ code.
I trust it helps.

Cheers,

Andrew

 'INKEY$_Play v2.BAS
 '
 'Plays with the use of INKEY$
 
 'TassyJims example
 '  do
 '   i$ = inkey$
 '  loop until i$<>""
 '
 '  DO : LOOP UNTIL INKEY$ = ""
 '  select case i$
 '  ...
 '
 Dim Integer I
 dim String In
 cls
 print "Press left, right, space or ESCAPE key"
 'MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM - Start of main loop
 do
   do
     ' test for keypresses
     In = INKEY$
   loop Until In <> ""
   DO : LOOP UNTIL INKEY$ = "" 'This is Jim's game-changer
   Select Case asc(In)
     Case 27     'ESCAPE
       Exit Do
     Case = 130  'Left
       GoLeft
     Case 131    'Right
       GoRight
     Case 32     'Space bar
       GoSpace        
   End Select
   'In = ""  Not necessary as it gets set to "" in the first pass in the DO
 Loop
 'mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm - end of main loop
 Print "Goodbye"
End
 
Sub GoLeft
 print "Left"
End Sub

Sub GoRight
 print "Right"
End Sub
 
Sub GoSpace
 print "Space"
End Sub
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025