Allegro checking if key held down using bool as a flag

I'm trying to make sure that input is taken based on separate keystrokes, not on every time the keyboard buffer is polled. This is what I have so far (only the pertinent information provided):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

void get_user_input();

int main(){

    init(); //all this does is initialize allegro and load the window and the 
            //board and the title bitmaps and draw them

    base_game_entity Simon; //this is the class for the game, not used yet
    bool key_pressed_flag = false; //this is my flag 

    masked_blit(board, screen, 0, 0, 200, 125, 400, 400);

    masked_blit(title, screen, 0, 0, 280, 0, 240, 100);

    destroy_bitmap(board);

    while(!key[KEY_ESC]){

        if(key_pressed_flag = false){

            get_user_input();
            key_pressed_flag = true;

        }

        if(key_pressed_flag = true){

            if(!key[KEY_7_PAD] && !key[KEY_9_PAD] && !key[KEY_3_PAD] &&
               !key[KEY_1_PAD]){

                key_pressed_flag = false;

            }

        }

    }

    allegro_exit();

}
END_OF_MAIN()

void get_user_input(){

    poll_keyboard();

    if(key[KEY_7_PAD]){

        green_selected = load_bitmap("green.bmp", NULL);

        if(!green_selected){

        allegro_message("ERROR LOADING GREEN");

        }

        masked_blit(green_selected, screen, 0, 0, 200, 125, 200, 200);

        destroy_bitmap(green_selected);

    }
    else if(key[KEY_9_PAD]){

        red_selected = load_bitmap("red.bmp", NULL);

        if(!red_selected){

        allegro_message("ERROR LOADING RED");

        }

        masked_blit(red_selected, screen, 0, 0, 400, 125, 200, 200);

        destroy_bitmap(red_selected);

    }
    else if(key[KEY_3_PAD]){

        blue_selected = load_bitmap("blue.bmp", NULL);

        if(!blue_selected){

        allegro_message("ERROR LOADING BLUE");

        }

        masked_blit(blue_selected, screen, 0, 0, 400, 325, 200, 200);

        destroy_bitmap(blue_selected);

    }
    else if(key[KEY_1_PAD]){

        yellow_selected = load_bitmap("yellow.bmp", NULL);

        if(!yellow_selected){

        allegro_message("ERROR LOADING YELLOW");

        }

        masked_blit(yellow_selected, screen, 0, 0, 200, 325, 200, 200);

        destroy_bitmap(yellow_selected);

    }

    board = load_bitmap("board.bmp", NULL);
    masked_blit(board, screen, 0, 0, 200, 125, 400, 400);
    destroy_bitmap(board);



}



The idea is that key_pressed_flag is supposed to be true whenever the function is called and the key is pressed. Then right before the loop restarts and the input function is called again, the computer checks to see if the user is still pressing one of the buttons. If none of the buttons is being pressed then the flag is reset back to false. If the flag is false then the function is called, but if it isn't then there is no function call and no input is read from the keyboard buffer. The problem is that when I run this code nothing happens. It loads everything including all the bitmaps but nothing happens when I press the appropriate keys. Without the flag and testing for the held key the function appears to work but if I hold down the button it keeps reading the keyboard buffer. Any ideas as to what could be causing this behavior are greatly appreciatedd
You should really use Allegro 5, its awesome - at first i didnt wanna switch over but once i did it was really awesome and all your programs are going to be much much more efficient, plus it automatically solves your problem
I want to. I've heard good things about it. But practically the whole API has changed and I don't have time to learn a new API. My book I'm using as reference uses allegro 4 and that's what I had always used, so for now I'm stuck. As it is this project is supposed to be done in Visual Basic 2010 but I asked my professor if I could do it in C++ because I'm better at C++ and I know how powerful allegro can be.
Lines 20 and 27, you're supposed to check for equality, not assigning:

if (key_pressed_flag == true)

And in your void get_user_input() function you should not be loading the bitmaps on every press of the key. Just load it once and store it in a variable or array.

Also, one technique to process a single keypress when the key is being held down is to use two boolean arrays: one for all the keys, second one to keep track if it's locked. And two functions: to check state of the keyboard and to lock a certain key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool all_keys[128];    // can use KEY_MAX for length
bool locked_keys[128];

// call this function on every loop
void check_state_of_keyboard()
{
    for (int i=0; i<128; i++) {
        if (!key[i]) {    // is key up?
            all_keys[i] = false;
            locked_keys[i] = false;
        }
        else {    // no, it's down
            all_keys[i] = !locked_keys[i];
        }
    }
}

void lock_key(int index)
{
    locked_keys[index] = true;
}


This way, you can process single keypresses by locking the key.

1
2
3
4
5
6
7
8
9
check_state_of_keyboard();

[...]

if (all_keys[KEY_W]) {
    do_something();
    // lock the key press
    lock_key(KEY_W);
}
Last edited on
its really not that much of a change, all allegro 4 projects can easily be converted to allegro 5 you really dont have to learn anything new :)


Lines 20 and 27, you're supposed to check for equality, not assigning:

if (key_pressed_flag == true)



This is what Visual Basic does to you. I can't believe I didn't see that. Thank you.

I'll also look into implementing those functions.

Okay well those functions didn't really work for me. I still get the same problem. I played around with it a bit and the most I got was that the image would get stuck and just stay highlighted.
You can use your old method but instead of assigning key_pressed_flag = true on line 23 have the get_user_input() function return whether or not the key was pressed.

key_pressed_flag = get_user_input();

Or just use if statements:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
check_keyboard_state();

if (all_keys[KEY_1_PAD) {
    do_something();
    lock_key(KEY_1_PAD);
}
else if (all_keys[KEY_3_PAD) {
    do_something();
    lock_key(KEY_3_PAD);
}
else if (all_keys[KEY_7_PAD) {
    do_something();
    lock_key(KEY_7_PAD);
}
else if (all_keys[KEY_9_PAD) {
    do_something();
    lock_key(KEY_9_PAD);
}


This means if you hold down any of the keys, the key will be processed just once, on the first press.
I got it using the if statements, but I had to include another if statement at the end to check if all the keys were clear so I could reset locked_keys[] because if not it would only work once. Thanks for your patience.
Topic archived. No new replies allowed.