QB64 Phoenix Edition
Trapping two keys - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: Trapping two keys (/showthread.php?tid=937)

Pages: 1 2


RE: Trapping two keys - PhilOfPerth - 10-02-2022

Bingo !!! This does everything I needed:

Print "Press any single or combo of cursor arrow keys...": Print
Do
ky = _KeyHit
_Limit 30
Select Case ky
Case Is = 18432 ' Up-arrow
If _KeyDown(19200) Then
Print "Up-arrow and Left-arrow"
ElseIf _KeyDown(19712) Then
Print "Up-arrow and Right-arrow"
Else Print "Up-arrow"
End If

Case Is = 19200 ' Left-arrow
If _KeyDown(18432) Then
Print "Left-arrow and Up-arrow"
ElseIf _KeyDown(20480) Then
Print "left-arrow and Down-arrow"
Else Print "Left-arrow"
End If

Case Is = 19712 ' Right-arrow
If _KeyDown(18432) Then
Print "Right-arrow and Up-arrow"
ElseIf _KeyDown(20480) Then
Print "Right-arrow and Down-arrow"
Else Print "Right-arrow"
End If

Case Is = 20480 ' Down-arrow
If _KeyDown(19200) Then
Print "Down-arrow and Left-arrow"
ElseIf _KeyDown(19712) Then
Print "Down-arrow and Right-arrow"
Else Print "Down-arrow"
End If

End Select
_KeyClear
Sleep 1: Cls
Loop

Thanks for the help bplus and Pete

Edit: I see that there are two reports for each double-combination, but don't see how to avoid this - yet.


RE: Trapping two keys - bplus - 10-02-2022

(10-02-2022, 12:04 AM)PhilOfPerth Wrote: ...

Edit: I see that there are two reports for each double-combination, but don't see how to avoid this - yet.

Code: (Select All)
Screen _NewImage(800, 600, 32)
_ScreenMove 250, 50
Do
    Cls
    If _KeyDown(19200) Then Print "Left ";
    If _KeyDown(19712) Then Print "Right ";
    If _KeyDown(18432) Then Print "Up ";
    If _KeyDown(20480) Then Print "Down";
    Print
    _Delay 1
Loop
because of the _delay there is a delayed reaction to key press, just hold them down a bit longer.


RE: Trapping two keys - Pete - 10-02-2022

If you want a reliable delay, don't use SLEEP. A key press interrupts SLEEP. Code SLEEP 60, run the program, and as soon as you press a key the sleep cycle is broken. _DELAT1 will always give a 1-second delay.

Another neat trick is to not delay the rest of the program at all, just delay the next key input...

Code: (Select All)
PRINT "Press any single or combo of cursor arrow keys...": PRINT
DO
    _LIMIT 30
    IF TIMER - z1 > .5 THEN
        ky = _KEYHIT
        IF ky THEN
            SELECT CASE ky
                CASE IS = 18432 ' Up-arrow
                    IF _KEYDOWN(19200) THEN
                        PRINT "Up-arrow and Left-arrow"
                    ELSEIF _KEYDOWN(19712) THEN
                        PRINT "Up-arrow and Right-arrow"
                    ELSE PRINT "Up-arrow"
                    END IF

                CASE IS = 19200 ' Left-arrow
                    IF _KEYDOWN(18432) THEN
                        PRINT "Left-arrow and Up-arrow"
                    ELSEIF _KEYDOWN(20480) THEN
                        PRINT "left-arrow and Down-arrow"
                    ELSE PRINT "Left-arrow"
                    END IF

                CASE IS = 19712 ' Right-arrow
                    IF _KEYDOWN(18432) THEN
                        PRINT "Right-arrow and Up-arrow"
                    ELSEIF _KEYDOWN(20480) THEN
                        PRINT "Right-arrow and Down-arrow"
                    ELSE PRINT "Right-arrow"
                    END IF

                CASE IS = 20480 ' Down-arrow
                    IF _KEYDOWN(19200) THEN
                        PRINT "Down-arrow and Left-arrow"
                    ELSEIF _KEYDOWN(19712) THEN
                        PRINT "Down-arrow and Right-arrow"
                    ELSE PRINT "Down-arrow"
                    END IF

            END SELECT
            _KEYCLEAR ' Remove this if you want each key pressed to register.
            z1 = TIMER
        END IF
    ELSE
        IF TIMER < z1 THEN z1 = z1 - 86400 ' Midnight adjustment.
    END IF
LOOP


I took out the CLS, so you could see the key progression. Easier to debug it that way. Lose the _KEYCLEAR if you want to peck away at the keyboard and have each key counted. If it is just about holding keys down, it's better to keep it.

My guess is you are looking for a way to move an RPG character up/down/right/left/and diagonal.

You will have to determine what, if any flags you need to set. For instance, right now a user can press three or more control keys.

Pete


RE: Trapping two keys - PhilOfPerth - 10-02-2022

You're right about what I intended.
Pressing 3 or more keys won't affect the game, except the player could get an unexpected direction as a result, but I would specify which 1 or 2 keys to use, so this shouldn't be a problem. I'll adjust or remove the _delay according to which prog it gets used in (I'll probably use this as part of my library of basic functions).  Smile


RE: Trapping two keys - bplus - 10-02-2022

"I liked the "simple" version better"
Code: (Select All)
_Title "Use arrow keys to move our hero."
heroX = 40: heroY = 12 ' middle
Do
    Cls
    Locate heroY, heroX: Print Chr$(1);
    If _KeyDown(19200) Then heroX = heroX - 1
    If _KeyDown(19712) Then heroX = heroX + 1
    If _KeyDown(18432) Then heroY = heroY - 1
    If _KeyDown(20480) Then heroY = heroY + 1
    If heroX < 1 Then heroX = 1
    If heroX > _Width Then heroX = _Width
    If heroY < 1 Then heroY = 1
    If heroY > _Height Then heroY = _Height
    _Limit 10
Loop



RE: Trapping two keys - Pete - 10-02-2022

@bplus

@PhilofPerth

Ah screw the simple version. Have a look at this...

https://qb64phoenix.com/forum/showthread.php?tid=939

It plays pretty well, eliminates illegal key presses, allows for and is code adjustable for slight discrepancies in timing on double key presses and releases, can have the movement speed adjusted on the fly, and allows for other key routines to be done simultaneously.

Pete

Edit: I have to edit every post on my old Firefox version to get those @ calls made into hypertext.


RE: Trapping two keys - mnrvovrfc - 10-02-2022

(10-02-2022, 05:20 PM)bplus Wrote: "I liked the "simple" version better"
If you used "_WIDTH" and "_HEIGHT" to limit where the player's hero moves, why not use them as well to place him/her on the screen at the beginning? What if the "SCREEN 0" dimensions were changed to 100 by 60 or something else?

Also those four "IF" statements could be enrolled into a single "IF" block featuring "ELSEIF" to make sure only one key is processed to move the player's hero. Unless of course the developer allows the player to move in diagonals...


RE: Trapping two keys - James D Jarvis - 10-02-2022

just use this line to set the middle if that's where you want them starting regardless of screen size:


heroX = Int(_Width / 2): heroY = Int(_Height / 2) ' middle


RE: Trapping two keys - bplus - 10-02-2022

"Also those four "IF" statements could be enrolled into a single "IF" block featuring "ELSEIF" to make sure only one key is processed to move the player's hero. Unless of course the developer allows the player to move in diagonals... "

Yeah the point of this thread is to respond to more than one keypress, so if down arrow and left arrow pressed the hero will go South-West and if up and down pressed the Hero would go nowhere they would cancel each other out.