Hi :) how know when a keyboard key is just being released
Blitz3D Forums/Blitz3D Programming/Hi :) how know when a keyboard key is just being released
| ||
Have an idea ? |
| ||
Check the time, between now, and the last time the key was down? |
| ||
good idea ! have you a piece of code ? |
| ||
sKey57Down=False While Not KeyHit(1) If KeyDown(57) Then sKey57Down=True ; Can also use KeyHit(57) If (Not KeyDown(57)) And sKey57Down=True Print "key 57 was just released!" sKey57Down=False EndIf Wend |
| ||
kuFlag = True ;beginning of loop kdFlag = KeyDown(?) If kdFlag = False and kuFlag = False ;do something here EndIf If kdFlag = True kuFlag = False Else kuFlag = True EndIf ;end of loop or kdFlag=False ;beginning of loop If KeyDown(?) kdFlag=True Else If kdFlag=True ;do something here kdFlag=False EndIf EndIf ;end of loop |
| ||
Or use a bidimensional array which stores the status of each key you need. Suppose you want to chek for the key code 57, 15 and 21 (57 should be space bar, I don't recall now, the rest are examples but you should get the drift). That are 3 keys to be tested, right ? So we can use a bidimensional array of three elements: dim ak(3,2) the first value is the keycode, the second is the status. So, at the beginning we can set up the array: ak(1,1) = 57 ;the key code ak(1,2) = 0 ;status: depressed ak(2,1) = 15 ;the key code ak(2,2) = 0 ;status: depressed ak(3,1) = 21 ;the key code ak(3,2) = 0 ;status: depressed Note that I ignore the ak(0) element here, you can optimize it if you like. Now, we can test for the key pressed and depressed: for n = 1 to 3 ;where 3 is the total number of keys to be tested if keydown(ak(n,1)) then ;if key is pressed then ;check if it the key has been pressed right now if ak(n,2) = 0 then ;the status was: depressed ;<----------------------------- KEY PRESSED ! endif ak(n,2) = 1 ;set the status to 'pressed' else ;the key is not pressed ;check if the key has been depressed right now if ak(n,2) = 1 then ;<----------------------------- KEY RELEASED ! endif ak(n,2) = 0 ;set the status to depressed endif next Hope this has sense for you, Sergio. |
| ||
Thx ! |
| ||
An idea for put in function ? i have truy Global kuFlag = True While Not KeyHit(1) If KeyUp(200) Then Print "HUUUP" EndIf If KeyUp(57) Then Print "HUUUP" EndIf Wend Function KeyUp(Key) kdFlag = KeyDown(Key ) If kdFlag = False And kuFlag = False good=True EndIf If kdFlag = True kuFlag = False Else kuFlag = True EndIf If Good=True Then Return Good EndIf End Function but don't work ;( |
| ||
Does this work better?Function KeyUp(Key) kdFlag = KeyDown(Key ) If kdFlag = False And kuFlag = False kuFlag = True Return True EndIf If kdFlag = True kuFlag = False Else kuFlag = True EndIf Return False End Function |
| ||
Voila!Global keybuf[255] Repeat MyUpdateKeyBuffer() ; Press 1 If MyKeyHit(2) DebugLog "Key 1 pressed at "+MilliSecs() End If ; Release 1 If MyKeyUp(2) DebugLog "Key 1 released at "+MilliSecs() End If Until MyKeyHit(1) Function MyKeyHit(i) If keybuf[i] = 1 Then Return True End Function Function MyKeyDown(i) If (keybuf[i] > 0) And (keybuf[i] < 3) Then Return True End Function Function MyKeyUp(i) If keybuf[i] = 3 Then Return True End Function Function MyUpdateKeyBuffer() For i = 1 To 255 Select keybuf[i] Case 0: ; Nothing If KeyDown(i) Or KeyHit(i) keybuf[i] = 1 End If Case 1: ; Key was hit in last update If KeyDown(i) keybuf[i] = 2 Else keybuf[i] = 3 End If Case 2: ; Key was held down in last update If KeyDown(i) = False keybuf[i] = 3 End If Case 3: ; Key was released in last update keybuf[i] = 0 End Select Next End Function |
| ||
No ?? strange ! but i have find another solution by type : Type TKeyUp Field Key Field Flag=True End Type Up=initkey(200) down=initkey(208) While Not KeyHit(1) If KeyUp(Up) Then Print "HUUUP" EndIf If KeyUp(Down) Then Print "HUUUP" EndIf Wend Function initkey(key) K.TKeyUp=New TKeyUp K\Key=Key K\Flag=True Return Handle(K) End Function Function KeyUp(Id) K.TKeyUp=Object.TKeyUp(Id) kdFlag = KeyDown(K\Key ) If kdFlag = False And k\Flag = False good=True EndIf If kdFlag = True k\Flag = False Else k\Flag = True EndIf If Good=True Then Return Good EndIf End Function |
| ||
Oh, I see, you were using the same flag for more than one key. Yeah, you have to use types, or arrays, or seperate variables for each key. |
| ||
I know in assembly language that when a key is pressed it returns a scan code and when it is released it returns a different scan code. That is how the system knows how long a key is held down. I used this in my code to prevent multiple enteries of the same key. I only checked for the key release scan code for each key, so the code didn't respond until you released the key. I don't think Blitz is taking advantage of this feature yet. But maybe someone will write a library for blitz that does. |
| ||
fredborg: try putting 'delay 400' at the end of the loop. it either wont catch the key or will always think its down. shambler, wolron, semar: suppose the key is pressed and quickly released while some other part of the programis being executed. I have a solution. I will post it |
| ||
this seems to always work the delays are to show that even if other parts of the program are taking a long time, one keydown/keyup will always be caught each loop. Dim hit(256),olddown(256),down(256),up(256) Print "begin" Repeat updatekeys() Delay 300 If hit(57) Then Print "hit" If up(57) Then Print "let go" If KeyHit(1) Then End Delay 300 Forever Function updatekeys() Local i For i=1 To 256 hit(i)=KeyHit(i)>0 down(i)=KeyDown(i) If hit(i) And olddown(i) Then up(i)=1 Else If hit(i) Then olddown(i)=1 up(i)=(olddown(i)=1 And down(i)=0) If up(i) Then olddown(i)=0 EndIf Next End Function |
| ||
Thanks for your help ! |
| ||
Coorae: Changed mine too :) |
| ||
@Fredborg > thanks for the code man.... I didn't ask for it but it helps.... Now all my menu actions take place upon release :P |