|
|
| Key Delay And Turn-Based Movement |
|
Gatleos
Member #12,534
January 2011
|
Before I start working with real-time sprite movement and timers, I decided to try something turn-based. So I programmed a simple set of functions to draw ASCII characters to the screen and am building a roguelike engine. But the main problem I keep running into is getting keyboard input. I can collect it just fine, the problem is that it's collected way too fast. Even tapping the key as lightly as possible detects two events at once! Is there a simple way to delay detection of key events? Current game loop (The Draw functions near the bottom blit ASCII characters to the screen): 1while(game_is_running)
2{
3al_wait_for_event(event_queue, &ev);
4//if(ev.type == ALLEGRO_EVENT_TIMER)
5if(key[KEY_DOWN])
6{
7//Game.y++;
8turn++;
9y++;
10}
11if(key[KEY_UP])
12{
13//Game.y--;
14turn++;
15y--;
16}
17if(key[KEY_LEFT])
18{
19//Game.x--;
20turn++;
21x--;
22}
23if(key[KEY_RIGHT])
24{
25//Game.x++;
26turn++;
27x++;
28}
29redraw = true;
30if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
31{
32break;
33}
34else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
35{
36 switch(ev.keyboard.keycode) {
37 case ALLEGRO_KEY_UP:
38 key[KEY_UP] = true;
39 break;
40
41 case ALLEGRO_KEY_DOWN:
42 key[KEY_DOWN] = true;
43 break;
44
45 case ALLEGRO_KEY_LEFT:
46 key[KEY_LEFT] = true;
47 break;
48
49 case ALLEGRO_KEY_RIGHT:
50 key[KEY_RIGHT] = true;
51 break;
52 }
53}
54 else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
55 switch(ev.keyboard.keycode) {
56 case ALLEGRO_KEY_UP:
57 key[KEY_UP] = false;
58 break;
59
60 case ALLEGRO_KEY_DOWN:
61 key[KEY_DOWN] = false;
62 break;
63
64 case ALLEGRO_KEY_LEFT:
65 key[KEY_LEFT] = false;
66 break;
67
68 case ALLEGRO_KEY_RIGHT:
69 key[KEY_RIGHT] = false;
70 break;
71
72 case ALLEGRO_KEY_ESCAPE:
73 game_is_running = false;
74 break;
75 }
76}
77if(redraw && al_is_event_queue_empty(event_queue))
78{
79redraw = false;
80
81al_clear_to_color(al_map_rgb(0,0,0));
82Win_Fill(46,Game,"green","black");
83Draw_Char(1,Game,x,y);
84//Draw_Str("Main Deck, Sector 7",Game,0,0,"white","blue",0);
85Win_Box(Game,219,"darkgrey","blue");
86Win_Box(Info,219,"darkgrey","blue");
87Win_Box(Message,219,"green","blue");
88itoa(turn,yis,10);
89Draw_Str("Turn:",Info,0,0,0);
90Draw_Str(yis,Info,5,0,0);
91//Win_FillRand(Game);
92al_flip_display();
93}
|
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
It's not your fault, but I'm so tired of seeing people struggle with getting key input. Allegro 4 should have higher level input functions. You're welcome to use my keyboard_handler. It's use is simple. Call SetupKeyHandler() near the beginning of your program. In your logic loop, call UpdateKeyHandler(time_passed), and then use : if (key_press(KEY_DOWN)) { do_stuff(); } It also has support for key release, key holds, keys open, key double clicks, and key_held_for(duration) as well as extending allegro's key codes to support various combinations of SHIFT, CTRL, and ALT. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
gnolam
Member #2,030
March 2002
|
[EDIT] -- |
|
Gatleos
Member #12,534
January 2011
|
Looks great! Where is KEY_MAX defined, though? I keep getting undefined errors.
|
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
You confused me. Without scrolling down to see the rest of your code I thought you were using Allegro 4 because you are checking if (key[KEY_DOWN]) {/*...*/}. Now that I look further down, you are using Allegro 5 and are trying to emulate A4 with it. My keyboard_handler is for Allegro 4 only at this point. So now, my advice is to drop use of your key array, and simply use the key press and release events that Allegro 5 provides for you. Ie... move the code for if (key[KEY_*]) {DoStuff();} into else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) { switch(ev.keyboard.keycode) { case ALLEGRO_KEY_UP: // key[KEY_UP] = true; The problem is that an entry from your key array will be true for several logic loops at a time. It takes at least a certain amount of time between key press and key release. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
Gatleos
Member #12,534
January 2011
|
Someone really needs to update that input tutorial if it's using jury-rigged code like that. It works much better now. One more question: what about key holds, double-taps, etc.? Is there a separate event for that or will I just have to make them myself?
|
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Gatleos said: Someone really needs to update that input tutorial if it's using jury-rigged code like that. What input tutorial? What's the link to it? Gatleos said: One more question: what about key holds, double-taps, etc.? Is there a separate event for that or will I just have to make them myself? There aren't any separate events for those, you'll have to track the state yourself. If you got a key down event, but haven't received a key up event then you have a key hold. For double clicks, you'll have to track the time of the last key down event and compare it to the time of the new key down event that matches it. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
Gatleos
Member #12,534
January 2011
|
Anyway, thanks for the help! Keyboard input is a lot easier than it seemed with that odd emulation of Allegro 4 the tutorial was trying to pull off.
|
|
Thomas Fjellstrom
Member #476
June 2000
|
Gatleos said: Someone really needs to update that input tutorial if it's using jury-rigged code like that. The code there is really only for really basic input needs. Something that only needs to know if a key is pressed at any given time. Trying to show something more complex would probably just confuse things more. I'm open to a second Keyboard tutorial showing more advanced concepts though. -- |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Yes, it's odd that the Allegro 5 Input Tutorial uses a key array instead of checking the key state with the Allegro 5 functions al_get_keyboard_state and al_key_down. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
Thomas Fjellstrom
Member #476
June 2000
|
Edgar Reynaldo said: Yes, it's odd that the Allegro 5 Input Tutorial uses a key array instead of checking the key state with the Allegro 5 functions al_get_keyboard_state and al_key_down. Not really. The keystate stuff is a dirty hack, imo worse than storing your own key array. Also its far less efficient. The tutorial only stores keys it needs, where as the keystate stuff stores all of them regardless. and copies them... -- |
|
|