menu selection changing
bartexsz

:-/

I have very basic problem...
In menu of my game while clicking down it's changing very fast. In Allegro 4 it was enough if I used rest() function. But in Allegro 5 I don't know how to handle this.

Can anybody give me idea for this?

I thought about something whith timer but don't know exactly what to do yet.

William Labbett
#SelectExpand
1int main() 2{ 3 4 bool down_key_pending = false; 5 bool up_key_pending = false; 6 OneRun OneRunObject = OneRun(); 7 8 if( OneRunObject.InitOkay() == false) 9 { 10 game_log(MAIN_LOG, "Problem initialising game.\n"); 11 pause_and_quit 12 } 13 14 15 16 Menu MainMenu("main_menu_bitmap_list.txt", "game_data/menu_bitmaps"); 17 18 Menu *CurrentMenu; 19 int cm_id = MAIN_MENU; /* current menu identifier */ 20 21 bool need_redraw = false; 22 23 bool hold_on_key_down_events = false; 24 25 int update_done = 0; 26 27 int time_of_key_down; 28 29 while( OneRunObject.ClearUpAndQuit() == false) 30 { 31 switch(cm_id) 32 { 33 case MAIN_MENU: 34 CurrentMenu = &MainMenu; 35 break; 36 } 37 38 al_wait_for_event(OneRunObject.q, &OneRunObject.event); 39 switch(OneRunObject.event.type) 40 { 41 case ALLEGRO_EVENT_DISPLAY_CLOSE: 42 OneRunObject.SetClearUpAndQuitFlag(); 43 CurrentMenu->SetNeedToActFlag(); 44 break; 45 case ALLEGRO_EVENT_KEY_DOWN: 46 47 if(hold_on_key_down_events == false) 48 { 49 OneRunObject.SetKeyState(ALLEGRO_EVENT_KEY_DOWN); 50 51 } 52 53 break; 54 case ALLEGRO_EVENT_KEY_UP: 55 OneRunObject.SetKeyState(ALLEGRO_EVENT_KEY_UP); 56 break; 57 case ALLEGRO_EVENT_TIMER: 58 59 need_redraw = true; 60 61 if(hold_on_key_down_events == false) 62 { 63 update_done = CurrentMenu->Update(OneRunObject.key_states); 64 } 65 66 if(update_done == 1 && hold_on_key_down_events == false) /* key down processed */ 67 { 68 hold_on_key_down_events = true; 69 time_of_key_down = al_get_timer_count(OneRunObject.timer); 70 } 71 else if(update_done == 2) /* Enter key pressed. */ 72 { 73 if(cm_id == MAIN_MENU) 74 { 75 switch(CurrentMenu->OptionSelected()) 76 { 77 case 0: /* Play. */ 78 OneRunObject.time_to_play = true; 79 break; 80 } 81 } 82 83 84 } 85
86 if(hold_on_key_down_events == true && *** al_get_timer_count(OneRunObject.timer) >= time_of_key_down + 20)
87 { 88 hold_on_key_down_events = false; 89 } 90 91 break; 92 } 93 94 95 96 if(need_redraw == true && al_event_queue_is_empty(OneRunObject.q)) 97 { 98 CurrentMenu->DrawMenu(); 99 } 100 101 102 103 104 if(OneRunObject.time_to_play == true) 105 { 106 /* if a loaded game was chosen, it should already be loaded */ 107 108 printf("start game here.\n"); 109 pause_and_quit(1); 110 } 111 112 113 al_flip_display(); 114 115 } 116 117 118 119 game_log(MAIN_LOG, "End of program. Returning 0.\n"); 120 return 0; 121}

Notice how the hold_on_key_down_events gets changed back to false after 20 ticks have passed since the last time a key down event was recieved.

Perhaps you can make sense of this.

I need to add another line so that 2 or more quick taps of a key all get processed.

/* EDIT : */

if(update_done == 1 && hold_on_key_down_events == false) /* key down processed */
{
             hold_on_key_down_events = true;
                     time_of_key_down = al_get_timer_count(OneRunObject.timer);
}

This bit sees if an update was done, ie the item selected changed, and then sets hold_on_key_down_events to true.

This is to stop further key down events from being processed until 20 ticks have passed.

/* EDIT *?

Also : crucially :

if(hold_on_key_down_events == false)
{          
   OneRunObject.SetKeyState(ALLEGRO_EVENT_KEY_DOWN);
            
}

this bit only changes the key states if hold_on_key_down_events is false, so if a ALLEGRO_EVENT_KEY_DOWN event resulted

in a key state being down, it'll stay as down, even though there's a key up event.

Also : look at this :

#SelectExpand
1#ifndef ONERUN_GUARD 2#define ONERUN_GUARD 3 4#include "globals.h" /* for UP_KEY, RIGHT_KEY, etc... */ 5 6#include "Game.h" 7 8 9 10 11 12class OneRun { 13 14 ALLEGRO_CONFIG *config_file_ptr; 15 16 int InitialiseDisplay(int fullscreen); 17 int InitialiseLog(void); 18 19 20 21 22 int start_fullscreen; 23 int show_fps; 24 25 enum MenuResult { CLEAR_UP_AND_QUIT }; 26 27 28 MenuResult menu_result; 29 30 31 Game *OneGame; 32 33 bool init_okay; 34 35 36 37 38 39 40 bool clear_up_and_quit; 41 42 public: 43 44 bool time_to_play; 45 46 ALLEGRO_EVENT_SOURCE *menu_enter_button_es; 47 48 ALLEGRO_EVENT_QUEUE *q; 49 ALLEGRO_EVENT event; 50 ALLEGRO_TIMER *timer; 51 52 int include_menu; 53 bool key_states[5]; 54 55 OneRun(); 56 57 int RunMenu( ); 58 59 void ActOnMenuResult(); 60 61 bool ClearUpAndQuit() { return clear_up_and_quit; } 62 63 void SetClearUpAndQuitFlag() { clear_up_and_quit = true; }; 64 65 bool InitOkay() { return init_okay; } 66 67 68 69 void SetKeyState(int up_or_down) 70 { 71 switch(this->event.keyboard.keycode) { 72 case ALLEGRO_KEY_UP: 73 this->key_states[UP_KEY] = up_or_down == ALLEGRO_EVENT_KEY_DOWN ? true : false; 74 break; 75 case ALLEGRO_KEY_RIGHT: 76 this->key_states[RIGHT_KEY] = up_or_down == ALLEGRO_EVENT_KEY_DOWN ? true : false; 77 break; 78 case ALLEGRO_KEY_DOWN: 79 this->key_states[DOWN_KEY] = up_or_down == ALLEGRO_EVENT_KEY_DOWN ? true : false; 80 break; 81 case ALLEGRO_KEY_LEFT: 82 this->key_states[LEFT_KEY] = up_or_down == ALLEGRO_EVENT_KEY_DOWN ? true : false; 83 break; 84 case ALLEGRO_KEY_ENTER: 85 this->key_states[ENTER_KEY] = up_or_down == ALLEGRO_EVENT_KEY_DOWN ? true : false; 86 break; 87 default: 88 break; 89 } 90 } 91}; 92 93 94#endif

Sorry if this is too complex.

Thread #608446. Printed from Allegro.cc