[A5] Non blocking keypressed
zelda007

Hi,

I would like to write a function that replaces the old keypressed() in Allegro 4.4 but this function must be non-blocking (because called in the game loop). I have found this link :
https://www.allegro.cc/forums/thread/610536

But it is blocking.

I try this :

bool keyPressed() {
            al_get_keyboard_state(&kbdstate);
            for (unsigned int i=0; i<ALLEGRO_KEY_MAX; ++i)
            {
                if (al_key_down(&kbdstate, i))
                    return true;
            }
            return false;
        }

But the al_get_keyboard_state() function seems to be very slow and slow down my loop. There was no problem with Allegro 4.4 and keypressed() function.

Is there a way to check if a key is waiting in the input buffer ?

Thanks

torhu

The "proper" way in Allegro 5 is to check for keyboard events in your event loop. If you just need to wait for an arbitrary keypress, you can do something like the code I posted in the thread to linked to.

If you are already in the event loop, waiting for any key is just this:

do
    al_wait_for_event(event_queue, &event);
while (event.type != ALLEGRO_EVENT_KEY_DOWN);

But you should probably check for at least ALLEGRO_EVENT_DISPLAY_CLOSE too, and set an "exit game" flag somewhere.

By the way, use <code></code> tags ;)

zelda007

Hi,

No it is not possible to use an event pool in my case because I need to continue executing the code even if the key is not pressed...

In fact, the exact behaviour of keypressed() in Allegro 4.4

My "loop" game :

#SelectExpand
1bool quit = false; 2while (!quit) { 3 4 // some code 5 6 /*** Here we must not block the execution ****/ 7 if (keypressed()) 8 { 9 // get the key pressed 10 int key = getKeyFunction(...); 11 if (key == ALLEGRO_KEY_DOWN) // do some stuff 12 else if (key == ALLEGRO_KEY_Q) quit = true; // quit for example 13 else if (......) // other stuff 14 } 15 /**********************************************/ 16 17 // some code 18 19} // end loop

Is there any way to do this ?

torhu

You can just empty the event loop each time, and ignore everything that you don't care about. You can use al_get_next_event, which doesn't block.

Not sure why you don't implement a proper event loop, though. Her is an example: https://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Timers

zelda007

OK I will try.

Because I don't really program a game with allego. It is an IA and I use Allegro only for displaying statistics. That is why I don't really have a game loop with FPS ans so on.

Thanks

torhu

Is this more or less what you need?

#SelectExpand
1ALLEGRO_EVENT_QUEUE *event_queue; 2ALLEGRO_EVENT event; 3bool quit = false; 4 5event_queue = al_create_event_queue(); 6al_register_event_source(event_queue, al_get_keyboard_event_source()); 7 8while (!quit) { 9 // some code 10 11 /*** Here we must not block the execution ****/ 12 while (al_get_next_event(event_queue, &event)) 13 { 14 if (event.type != ALLEGRO_EVENT_KEY_DOWN) 15 continue; 16 17 switch (event.keyboard.keycode) 18 { 19 case ALLEGRO_KEY_DOWN: // do some stuff 20 break; 21 case ALLEGRO_KEY_Q: 22 quit = true; // quit for example 23 break; 24 default: // other stuff 25 break; 26 } 27 } 28 /**********************************************/ 29 // some code 30 31} // end loop 32 33al_destroy_event_queue(event_queue);

tobing

Or maybe you want to use

to retrieve the current state of your keyboard, then use

to check if a specific key is pressed in that state.

Thread #616837. Printed from Allegro.cc