|
This thread is locked; no one can reply to it. |
1
2
|
Key State |
AceBlkwell
Member #13,038
July 2011
|
I'm working with the directional key state macros "key[KEY_UP]" type thing. It works well if you are moving a bit map around the screen. However, not so good if you just want to read which cell a person is moving to. I won't bore everyone with the details of the game. but here is a rough idea of what I'm doing 1)Player has a board (like checkers, sorta) with a current status. Anyways, my problem is when the up (in this case) arrow is hit, it actually buffers several times and I've got no way of emptying the buffer. I've tried clear_buf but didn't do anything. I've tried a while(keypressed); loop thinking it would run through the loop until a key press wasn't detected but it locks in the loop. I know I can use readkey() and use letters like a,s,d,w, but would rather use the arrow keys. Unless there is a way I haven't found yet, I can't get readkey to do anything with arrow key scans. In short, is there a way of emptying the key buffer using arrow keys or is there a difference key scan that works with readkey()/clear_buf and arrow keys. Thanks in advance for the attention. |
Dizzy Egg
Member #10,824
March 2009
|
Wouldn't something like this help? bool allowUp = true; if (upKey) { //Up Key Pressed allowUp = false; } else if(!upKey){ allowUp = true; }
---------------------------------------------------- |
Niunio
Member #1,975
March 2002
|
You can change the "key" array content. For example: if (key[KEY_UP]) { MoveUp (); KeyUpPressed = TRUE; KeyDownPressed = KeyLeftPressed = KeyRightPressed = FALSE; } [edit] I'm so so slow...:-[ ----------------- |
AceBlkwell
Member #13,038
July 2011
|
The problem with changing the key up value or using a secondary value, is it doesn't eliminate the scanned keys. IE User its key up,the buffer reads So if I change the keyup to read false (0) then the second scan key up comes back and says true. Key in mind, when running a key[XXX] while loop, the loop runs continously. So changing the internal key[UP] to 0 , only works for that one trip through the loop. The next time through the loop and it scans the key board, it's going to see there are more key[ups] in waiting and will react accordingly. I have to empty the buffer some how. However, I will trial these just to make sure my understanding of the process isn't wrong. Thanks guys, |
gnolam
Member #2,030
March 2002
|
Niunio said: You can change the "key" array content. Bad Niunio! Bad! The key array should be treated as read-only. Anyway. Solution: 1char keyBuffer[KEY_MAX];
2
3void input(void)
4{
5 // Do something once when KEY_UP is pressed
6 if (key[KEY_UP] && !keyBuffer[KEY_UP]) {
7 foo();
8 }
9
10 // Do something once when KEY_UP is released
11 if (!key[KEY_UP] && keyBuffer[KEY_UP]) {
12 bar();
13 }
14
15 // Do something every cycle while KEY_UP is down
16 if (key[KEY_UP]) {
17 baz();
18 }
19
20 for (int i = 0; i < KEY_MAX; i++) {
21 keyBuffer[i] = key[i];
22 }
23}
-- |
Arthur Kalliokoski
Second in Command
February 2005
|
gnolam said: Bad Niunio! Bad! The key array should be treated as read-only. It looked to me like he had cloned variables that he was altering, not the actual Allegro key array. They all watch too much MSNBC... they get ideas. |
David Sopala
Member #5,056
September 2004
|
Check for release and not for press. 1bool keyrel(int k)
2{
3 static bool initialized = false;
4 static bool keyp[KEY_MAX];
5
6 if(!initialized)
7 {
8 // Set the keyp (key pressed) flags to false
9 for(int i = 0; i < KEY_MAX; i++) keyp[i] = false;
10 initialized = true;
11 }
12
13 // Now for the checking
14 // Check if the key was pressed
15 if(key[k] && !keyp[k])
16 {
17 // Set the flag and return
18 keyp[k] = true;
19 return false;
20 }
21 else if(!key[k] && keyp[k])
22 {
23 // The key was released
24 keyp[k] = false;
25 return true;
26 }
27 // Nothing happened?
28 return false;
29}
<img src="http://imgur.com/bfHvGkj.jpg" /> |
AceBlkwell
Member #13,038
July 2011
|
Thanks all, I'll give it a try. Sorry if my paraphrasing of the actual KEY array command confused those trying to help. The whole key pressed Vs key released may give me a work around as you guys have shown. I did have one concern however, if the Player hits up and then releases, how many times will the combination Up and press be true before the player can release the key? I'm hoping the solution will allow me... Again, the only potential issue I can see from the solution, not having tried them, would be if the up and pressed conditions are read 5-6 times before the player turns loose of the key. I guess I could add a third condition that starts false and trues the first time through the if statment. Then when I get key released scan, can falsify it again. Just thinking out loud. Thanks again to all and I'll update the page once I try the solution. Ace |
Dizzy Egg
Member #10,824
March 2009
|
The key can't hit 5 times in one pass of a loop, it's impossible. Show your code, somethings wrong.
---------------------------------------------------- |
Specter Phoenix
Member #1,425
July 2001
|
I used to get the same feedback when I did keypress for debugging. I made it so that when a key was pressed it would output debug info to a file. When I opened the file it would have about 5 or so for each key press. Not sure if that is what he is talking about but the code I used was the code from Tomasu's wiki tutorials. I did if (keys[KEY_UP]){ outfile << "Debug coords:" << x << ", " << y << "\n";} Output would be like: Debug coords: 3, 4
|
AceBlkwell
Member #13,038
July 2011
|
Specter Phoenix is correct, When I print something out, it shows the key to hit 4-5 times. I won't bore everyone with the entire code given I'm just testing different aspects until I have all the components working. But here is essentially what I have (I'm just including one key for the sake of demonstration. while(key[ESC]){ if(key[KEY_UP]) this is a little skeleton compared to what I have but the issue is the same. And yes I know I can't see the print out until I drop out of graphics mode. But when I do I see 4-5 "Yo"s when I actually only hit the up arrow for a second. This tells me one of two things have to be true. So now I either need to either change the condition of #1 to look for a key release (as suggested above) after the first key[UP] is true or if #2 is true I need a way of depleting the key buffer given I can't find a way to clear on command. Thanks for the suggestions |
David Sopala
Member #5,056
September 2004
|
The loop runs fast use key_rel instead of checking if the key is pressed. your checking a bool very quickly here and it will input 5 if not more times 1#include <allegro.h>
2#include <conio.h>
3
4using namespace std;
5
6
7bool keyrel(int k);
8
9int main()
10{
11 //ini allegro kb and such
12 while(!key[KEY_ESC])
13 {
14 if(keyrel(KEY_UP))
15 {
16 cout<<"Yo!"<<endl;
17 }
18 }
19}
20END_OF_MAIN()
21
22bool keyrel(int k)
23{
24 static bool initialized = false;
25 static bool keyp[KEY_MAX];
26
27 if(!initialized)
28 {
29 // Set the keyp (key pressed) flags to false
30 for(int i = 0; i < KEY_MAX; i++) keyp[i] = false;
31 initialized = true;
32 }
33
34 // Now for the checking
35 // Check if the key was pressed
36 if(key[k] && !keyp[k])
37 {
38 // Set the flag and return
39 keyp[k] = true;
40 return false;
41 }
42 else if(!key[k] && keyp[k])
43 {
44 // The key was released
45 keyp[k] = false;
46 return true;
47 }
48 // Nothing happened?
49 return false;
50}
<img src="http://imgur.com/bfHvGkj.jpg" /> |
Specter Phoenix
Member #1,425
July 2001
|
I'll paste code from the movement code and the output file. if(key[KEY_UP] && cell_y >= 4.0) { cell_y -= 4.0; outfile << "KEY_UP == X: " << cell_x << ", Y: " << cell_y << "\n"; } Sample Output KEY_RIGHT == X: 208, Y: 148 KEY_RIGHT == X: 212, Y: 148 KEY_RIGHT == X: 216, Y: 148 KEY_RIGHT == X: 220, Y: 148 KEY_DOWN == X: 220, Y: 152 KEY_DOWN == X: 220, Y: 156 KEY_DOWN == X: 220, Y: 160 KEY_LEFT == X: 216, Y: 160 KEY_LEFT == X: 212, Y: 160 KEY_LEFT == X: 208, Y: 160 KEY_UP == X: 208, Y: 156 KEY_UP == X: 208, Y: 152 KEY_UP == X: 208, Y: 148 That is just a quick press on each key.
|
gnolam
Member #2,030
March 2002
|
And this is why people get disillusioned with helping people code. -- |
Specter Phoenix
Member #1,425
July 2001
|
gnolam said: And this is why people get disillusioned with helping people code. Yeah, but I'm not asking for help, just illustrating what is happening. I've learned asking for help is a waste because you get too many varied answers and normally none of them are close to your coding style so you end up still lost. I got to the point, over the years, to where I just act like I had a clue what they said and then skip what I was getting help with and come up with something else to code. I was doing an address book, and got stuck on something, so moved on to pong, got stuck on pong and moved to learning perl, got stuck on perl and learned ruby, got stuck their and went back to coding simple apps that I knew how to do.
|
Dizzy Egg
Member #10,824
March 2009
|
WE'VE ALREADY SAID 100 TIMES, FLAG THE KEY AS BEING PRESSED UP ON THE FIRST PASS OF THE LOOP AND DON'T RESET THE FLAG UNTIL THE KEY IS RELEASED
---------------------------------------------------- |
Specter Phoenix
Member #1,425
July 2001
|
Dizzy Egg said: WE'VE ALREADY SAID 100 TIMES, FLAG THE KEY AS BEING PRESSED UP ON THE FIRST PASS OF THE LOOP AND DON'T RESET THE FLAG UNTIL THE KEY IS RELEASED So this is wrong (from Tomasu's Movement Tutorial): enum MYKEYS{KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT}; bool key[4] = {false, false, false, false}; while(!doexit) { else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) { } else if(ev.type == ALLEGRO_EVENT_KEY_UP) { } } Which brings up the question: What is the point of a wiki if the examples are wrong and never corrected with the "100 times" repeat so you didn't have to say it 100 times? [REVISION]
|
LennyLen
Member #5,313
December 2004
|
Specter Phoenix said: So this is wrong (from Tomasu's Movement Tutorial): No, because you've failed to understand the code. What it does is set a flag for each direction if a specific key is being pressed, and then unset it when the key is released. If the flags are set, then various things happen, otherwise they don't. The key[] array in Tomasu's example is not the same as the key[] array in A4.
|
Specter Phoenix
Member #1,425
July 2001
|
LennyLen: I understand the code, but I was trying to point out that even with Tomasu's A5 code it still prints out multiple lines with one press. I simply copied and pasted the code, added file i/o to each key, and when I just pressed it once I got the 3 or 4 lines per press.
|
LennyLen
Member #5,313
December 2004
|
Specter Phoenix said: LennyLen: I understand the code, but I was trying to point out that even with Tomasu's A5 code it still prints out multiple lines with one press. I simply copied and pasted the code, added file i/o to each key, and when I just pressed it once I got the 3 or 4 lines per press. That's how it's supposed to work with the Wiki example. It's a movement example, so it's supposed to continue to move for as long as the key is held down.
|
Specter Phoenix
Member #1,425
July 2001
|
LennyLen said: That's how it's supposed to work with the Wiki example. It's a movement example, so it's supposed to continue to move for as long as the key is held down. Yeah but I'm not holding it down. I just do one quick keypress of say left and the file io shows 3 or 4 outputs for just one quick keypress. Like if I press 'a' to make a and had file io attached to that key that outputs say "Hello", I would have an output file that would have Hello Hello Hello Hello just for one press of a.
|
Niunio
Member #1,975
March 2002
|
gnolam said: Bad Niunio! Bad! I know. It's bad because it will be changed by "key repetition". Anyway, my second approach (using auxiliary variables or an array as you suggest) would work here. ----------------- |
LennyLen
Member #5,313
December 2004
|
Specter Phoenix said: Yeah but I'm not holding it down. I just do one quick keypress of say left and the file io shows 3 or 4 outputs for just one quick keypress. As far as the hardware is concerned, that is holding it down. It's a lot quicker than you are.
|
Specter Phoenix
Member #1,425
July 2001
|
LennyLen said: As far as the hardware is concerned, that is holding it down. It's a lot quicker than you are. Is there a way to fix it? Rather annoying to sift through a file of 100 lines of debug data when each one has 3 unneeded duplicates.
|
Arvidsson
Member #4,603
May 2004
|
Specter Phoenix said: Is there a way to fix it? Fix what exactly? If you want something to be logged when you press a key you check for a pressed key, and not if it's held down or not.
|
|
1
2
|