Posts: 652
Threads: 96
Joined: Apr 2022
Reputation:
22
Is there a command that can identify two keys pressed together, like up-curor+left-cursor? and if so, how can I ensure that enough time is allowed for any slight discrepancy in the time they were pressed?
Posts: 3,964
Threads: 176
Joined: Apr 2022
Reputation:
219
10-01-2022, 01:59 AM
(This post was last modified: 10-01-2022, 01:59 AM by bplus.)
_keydown(key number) will tell whether a particular key code is being pressed the moment you call it
So upArrow = _keydown(18432) ' IDE menu Tools > Insert Keycode gets 18432 when press up arrow
leftArrow = _keydown(19200)
b = b + ...
Posts: 652
Threads: 96
Joined: Apr 2022
Reputation:
22
I tried this, but it doesn't work:
get1:
k = _KeyHit
If k < 1 Then GoTo get1
get2:
l = _KeyHit
If l < 1 Then GoTo get2
n = k + l
Print l;
GoTo get1
Late edit: Thanks bplus; I didn't see your response til I edited my entry. I'll go and experiment with your explanation.
Posts: 3,964
Threads: 176
Joined: Apr 2022
Reputation:
219
10-01-2022, 02:26 AM
(This post was last modified: 10-01-2022, 02:26 AM by bplus.)
kh& = _keyhit 'is fine too,
Select case kh& ' but _Keydown works great for detecting multiple keys
case 18432 ' then up arrow
if _keydown(19200) then ' up and left arrows both
b = b + ...
Posts: 2,169
Threads: 222
Joined: Apr 2022
Reputation:
103
To demo what Mark is gettting at...
Code: (Select All) DO
_LIMIT 30
IF _KEYDOWN(18432) THEN h = -1 ELSE h = 0
IF _KEYDOWN(19200) THEN i = -1 ELSE i = 0
IF h * i = 1 THEN PRINT "Both keys down." ELSE IF LEN(INKEY$) THEN CLS
_KEYCLEAR
LOOP
I threw in the INKEY$ statement just to only clear the screen when a key is pressed, other than the combo you wanted, arrow up and left.
Now if you hold both down, the process will repeat. If you only want one event, then do this...
Code: (Select All) DO
_LIMIT 30
IF _KEYDOWN(18432) THEN h = -1 ELSE h = 0
IF _KEYDOWN(19200) THEN i = -1 ELSE i = 0
IF h * i = 1 AND flag = 0 THEN
PRINT "Both keys down."
flag = -1
ELSE
IF h * i = 0 THEN flag = 0: CLS
END IF
_KEYCLEAR
LOOP
Hope that helps.
Pete
Posts: 652
Threads: 96
Joined: Apr 2022
Reputation:
22
10-01-2022, 08:05 AM
(This post was last modified: 10-01-2022, 08:20 AM by PhilOfPerth.)
@Pete:
Yes, that does help. I'm starting to see the result I want now, but I'll need to fiddle around a bit.
I want to detect and act on any of the 8 combinations for the cursor-keys.
I think this can be extended to do that. Thanks both.
Late edit: Nearly got it!
getKeys:
ky = 0
Do
If _KeyHit < 1 Then GoTo getKeys
If _KeyDown(18432) Then ky = ky + 1
If _KeyDown(19200) Then ky = ky + 2
If _KeyDown(19712) Then ky = ky + 4
If _KeyDown(20480) Then ky = ky + 8
Print ky
_KeyClear
_Limit 30
Loop
Posts: 2,169
Threads: 222
Joined: Apr 2022
Reputation:
103
Here are two examples that do the same thing, but have different coding formats...
Code: (Select All) LINE INPUT "Input 1 for simple or 2 for complex demo: "; ans$
IF ans$ = "" THEN END
IF ans$ = "1" OR ans$ = "2" THEN ELSE BEEP: CLS: RUN
CLS
PRINT "Press any 2-combo of cursor arrow keys...": PRINT
IF ans$ = "1" THEN
DO
_LIMIT 30
IF _KEYHIT < 1 THEN
IF _KEYDOWN(18432) AND _KEYDOWN(19200) THEN
IF flag = 0 THEN PRINT "a & b": flag = -1
ELSEIF _KEYDOWN(18432) AND _KEYDOWN(19712) THEN
IF flag = 0 THEN PRINT "a & c": flag = -1
ELSEIF _KEYDOWN(18432) AND _KEYDOWN(20480) THEN
IF flag = 0 THEN PRINT "a & d": flag = -1
ELSEIF _KEYDOWN(19200) AND _KEYDOWN(19712) THEN
IF flag = 0 THEN PRINT "b & c": flag = -1
ELSEIF _KEYDOWN(19200) AND _KEYDOWN(20480) THEN
IF flag = 0 THEN PRINT "b & d": flag = -1
ELSEIF _KEYDOWN(19712) AND _KEYDOWN(20480) THEN
IF flag = 0 THEN PRINT "c & d": flag = -1
END IF
END IF
IF flag THEN
a = _KEYDOWN(18432) + _KEYDOWN(19200) + _KEYDOWN(19712) + _KEYDOWN(20480)
IF a = 0 THEN flag = 0: CLS
END IF
LOOP
ELSE ' Demo 2.
REDIM flag(4)
DO
LOCATE 3, 1: PRINT "ky ="; ky
_LIMIT 30
IF flag2 = 0 THEN
IF _KEYDOWN(18432) AND flag(1) = 0 THEN ky = ky + 1: flag(1) = -1
IF _KEYDOWN(19200) AND flag(2) = 0 THEN ky = ky + 2: flag(2) = -1
IF _KEYDOWN(19712) AND flag(3) = 0 THEN ky = ky + 4: flag(3) = -1
IF _KEYDOWN(20480) AND flag(4) = 0 THEN ky = ky + 8: flag(4) = -1
END IF
IF ky THEN
SELECT CASE ky
CASE 3
IF flag2 = 0 THEN
PRINT "a & b"
flag2 = -1
ELSE
GOSUB flag_check
END IF
CASE 5
IF flag2 = 0 THEN
PRINT "a & c"
flag2 = -1
ELSE
GOSUB flag_check
END IF
CASE 6
IF flag2 = 0 THEN
PRINT "b & c"
flag2 = -1
ELSE
GOSUB flag_check
END IF
CASE 9
IF flag2 = 0 THEN
PRINT "a & d"
flag2 = -1
ELSE
GOSUB flag_check
END IF
CASE 10
IF flag2 = 0 THEN
PRINT "b & d"
flag2 = -1
ELSE
GOSUB flag_check
END IF
CASE 12
IF flag2 = 0 THEN
PRINT "c & d"
pete = 1
flag2 = -1
ELSE
GOSUB flag_check
END IF
CASE ELSE
GOSUB flag_off
END SELECT
_KEYCLEAR
END IF
LOOP
END IF ' Demo loop.
flag_check:
a = _KEYDOWN(18432) + _KEYDOWN(19200) + _KEYDOWN(19712) + _KEYDOWN(20480)
IF a = 0 THEN GOSUB flag_off
RETURN
flag_off:
ky = 0: REDIM flag(4): flag2 = 0: CLS
RETURN
Pete
Posts: 3,964
Threads: 176
Joined: Apr 2022
Reputation:
219
10-01-2022, 03:33 PM
(This post was last modified: 10-01-2022, 03:45 PM by bplus.)
Just a note about _KeyClear, it won't help with _KeyDown(), it will clear Inkey$ or _KeyHit.
This is interesting:
Code: (Select All) If _KeyDown(18432) Then ky = ky + 1
If _KeyDown(19200) Then ky = ky + 2
If _KeyDown(19712) Then ky = ky + 4
If _KeyDown(20480) Then ky = ky + 8
Instead of _KeyClear you could set ky = 0 but it would be more direct to just execute code like if left arrow then x = x-1 if right arrow then x = x+1, if up arrow then y = y - 1, if down arrow then y = y + 1.
You don't need any GetKey sub with _Keydown(), again it tells you immediately when key number is being held down.
Your problem with _keydown is going to be getting user to release key so several calls doing same thing aren't executed but my alternate suggestion is good for moving character around screen.
Quick HeroX, HeroY moving on screen:
Code: (Select All) Screen _NewImage(800, 600, 32)
_ScreenMove 250, 50
heroX = 400: heroY = 300 ' middle
Do
Cls
Circle (heroX, heroY), 10
If _KeyDown(19200) Then heroX = heroX - 5
If _KeyDown(19712) Then heroX = heroX + 5
If _KeyDown(18432) Then heroY = heroY - 5
If _KeyDown(20480) Then heroY = heroY + 5
_Limit 10
Loop
b = b + ...
Posts: 2,169
Threads: 222
Joined: Apr 2022
Reputation:
103
Interesting about _KEYCLEAR. I never use _KEYDOWN, oh, there was that one time, but I didn't like it, so back to INKEY$. I like using _KEYCLEAR with INKEY$. It used to be a WHILE:WEND snippet was needed, or a null variable assigned to INKEY$ to have this type of effect on the key buffer. Nice to know it isn't needed with _KEYDOWN, even though I probably won't be using it in my own routines.
@PhilOfPerth just be aware in your attempt with ky values, they won't add up properly unless you take the ones held down out of the next iteration. If you've ever watched The Big Band Theory, this is where Sheldon Cooper says have, "Fun with Flags!" In the code I wrote for you in post #7, demo 2 in the single coded example uses (2) flags to control the ky addition process and to limit the print statement to just one printing while the key combo is held down. Demo one uses (1) flag variable in a more simplistic manner, just to recognize one operation was performed and no others will occur until the key combo is released.
Pete
Posts: 652
Threads: 96
Joined: Apr 2022
Reputation:
22
That's great!
I liked the "simple" version better - it gave the same results for my application, and was clearer. Simple is always good for me, suits my personality.
I'm going to use that, with mods to trap single-cursor as well. May experiment with select case with it.
|