Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Keyboard not responding to Input

This thread is locked; no one can reply to it. rss feed Print
Keyboard not responding to Input
Reaper
Member #8,737
June 2007

Hello Everyone, I'm new here. I'm currently programming a program for a College assignment and I've run into a problem - they program isn't responding the the user input. Everything else is working fine, but when the user presses a key, nothing happens. I think this has got something to do with the order that I call various functions (e.g. moveplayer() and setupgame()) in my main() function, but I'm not really too sure. If anyone could take a look at my code and make any suggestions it would be very much appreciated. Thanks.

1#include <allegro.h>
2 
3BITMAP* box;
4BITMAP* buffer;
5 
6int x = 15;
7int y = 11;
8 
9int tempX = 15;
10int tempY = 11;
11 
12int boxes;
13 
14int map[24][32] = {}; //Removed map data
15 
16int objMap[24][32] = {}; //Removed object map data
17 
18void setupGame(){
19 
20 buffer = create_bitmap( 640, 480);
21 box = load_bitmap( "coin.bmp", NULL);
22 boxes = 1;
23 
24 for (int i = 0; i <= 24; i++){
25 
26 for( int t = 0; t <= 32; t++){
27 
28 if( map<i>[t] == 1) rectfill( buffer, t * 20, i * 20, (t + 1) * 20, (i + 1) * 20, makecol( 128, 255, 255));
29 else if( map<i>[t] == 2) rectfill( buffer, t * 20, i * 20, (t + 1) * 20, (i + 1) * 20, makecol( 255, 128, 0));
30 else if( map<i>[t] == 3) rectfill( buffer, t * 20, i * 20, (t + 1) * 20, (i + 1) * 20, makecol( 255, 0, 0));
31 else if( map<i>[t] == 4) rectfill( buffer, t * 20, i * 20, (t + 1) * 20, (i + 1) * 20, makecol( 0, 0, 0));
32 
33 }
34 
35 }
36 
37 for (int i = 0; i <= 24; i++){
38 
39 for( int t = 0; t <= 32; t++){
40 
41 if( objMap<i>[t] == 100) circlefill( buffer, (t * 20) + 10, (i * 20) + 10, 10, makecol( 255, 255, 0));
42 else if( objMap<i>[t] == 101) draw_sprite( buffer, box, t * 20, i * 20);
43 
44 }
45 
46 }
47 
48 draw_sprite( screen, buffer, 0, 0);
49 
50}
51 
52void movePlayer(){
53 
54 tempX = x;
55 tempY = y;
56 
57 if ( key[KEY_UP] && map[y - 1][x] == 3){
58 
59 if( objMap[y - 1][x] = 101){
60 --y;
61 } else if( objMap[y - 1][x] == 101 && map[y - 2][x] == 3 || objMap[y - 1][x] == 101 && map[y - 2][x] == 4){
62 
63 if (map[y - 2][x] == 4) --boxes;
64 
65 objMap[y - 2][x] = 101;
66 
67 --y;
68 }
69 
70 } else if ( key[KEY_DOWN] && map[y + 1][x] == 3){
71 
72 if( objMap[y + 1][x] = 101){
73 ++y;
74 } else if( objMap[y + 1][x] == 101 && map[y + 2][x] == 3 || objMap[y + 1][x] == 101 && map[y + 2][x] == 4){
75 
76 if (map[y + 2][x] == 4) --boxes;
77 
78 objMap[y + 2][x] = 101;
79 
80 ++y;
81 }
82 
83 } else if ( key[KEY_RIGHT] && map[y][x + 1] == 3){
84 
85 if( objMap[y][x + 1] = 101){
86 ++x;
87 } else if( objMap[y][x + 1] == 101 && map[y][x + 2] == 3 || objMap[y][x + 1] == 101 && map[y][x + 2] == 4){
88 
89 if (map[y][x + 2] == 4) --boxes;
90 
91 objMap[y][x + 2] = 101;
92 
93 ++x;
94 }
95 
96 } else if ( key[KEY_LEFT] && map[y][x - 1] == 3){
97 
98 if( objMap[y][x - 1] = 101){
99 --x;
100 } else if( objMap[y][x - 1] == 101 && map[y][x - 2] == 3 || objMap[y][x - 1] == 101 && map[y][x - 2] == 4){
101 
102 if (map[y][x - 2] == 4) --boxes;
103 
104 objMap[y][x - 2] = 101;
105 
106 --x;
107 }
108 
109 }
110 
111 
112 acquire_screen();
113 
114 rectfill( buffer, tempX * 20, tempY * 20, (tempX + 1) * 20, (tempY + 1) * 20, makecol( 255, 0, 0));
115 
116 circlefill( buffer, (x * 20) + 10, (y * 20) + 10, 10, makecol( 255, 255, 0));
117 
118 draw_sprite( screen, buffer, 0, 0);
119 release_screen();
120 
121 objMap[tempY][tempX] = 0;
122 objMap[y][x] = 101;
123 
124 if ( boxes)
125 {
126 textout_ex( screen, font, "Copyright Bede Morrissey, 2007", 5, 466, makecol(0, 0, 0), makecol(255, 128, 0));
127 
128 }
129 
130 
131 rest(100);
132}
133 
134volatile int speed_counter = 0;
135 
136void increment_speed_counter()
137{
138 speed_counter++;
139}
140 
141int main(){
142 
143 allegro_init();
144 install_keyboard();
145 set_color_depth(16);
146 set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
147 
148 setupGame();
149 
150 BITMAP *bmpBackBuffer = create_bitmap(640,480);
151 install_int_ex(increment_speed_counter, BPS_TO_TIMER(1)); //should this be 1 or 60?
152 int seccount = 0;
153 while (!key[KEY_ESC])
154 {
155 while (speed_counter > 0)
156 {
157 seccount++;
158 speed_counter--;
159 }
160 clear(bmpBackBuffer);
161 textprintf_ex(bmpBackBuffer, font, 5, 5, makecol(255, 255, 255), 1, "Secs: %d", seccount);
162 blit(bmpBackBuffer,screen,0,0,0,0,70,20);
163 }
164 
165 while( !key[KEY_ESC])
166 {
167 movePlayer();
168 }
169 
170 return 0;
171}
172END_OF_MAIN();

gnolam
Member #2,030
March 2002
avatar

movePlayer() will never be called. When you exit the first loop, key[ESC] will still be set, and the second loop will be skipped. That's your main problem. As soon as you've fixed that, however, you'll discover why mixing logic and drawing is a bad idea...

Quote:

install_int_ex(increment_speed_counter, BPS_TO_TIMER(1)); //should this be 1 or 60?

That should be however many logic updates you want per second.

There are more errors and bad practices in there (like not destroying bitmaps you create), but that's as much as I'm willing to correct until the first two items are fixed: move movePlayer() into the actual timed loop, and separate your logic and drawing (see the FAQ for a hint on how it should look) and I'll tell you the rest.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Reaper
Member #8,737
June 2007

Thank you very much, gnolam. I have moved my movePlayer() function into the main loop and it now looks like this:

1int main()
2{
3 allegro_init();
4 install_keyboard();
5 set_color_depth(16);
6 set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
7 
8 setupGame();
9 
10 BITMAP *bmpBackBuffer = create_bitmap(640,480);
11 install_int_ex(increment_speed_counter, BPS_TO_TIMER(1)); //should this be 1 or 60?
12 int seccount = 0;
13 while (!key[KEY_ESC])
14 {
15 while (speed_counter > 0)
16 {
17 movePlayer();
18 seccount++;
19 speed_counter--;
20 }
21 clear(bmpBackBuffer);
22 textprintf_ex(bmpBackBuffer, font, 5, 5, makecol(255, 255, 255), 1, "Secs: %d", seccount);
23 blit(bmpBackBuffer,screen,0,0,0,0,70,20);
24 }
25 
26 return 0;
27}
28END_OF_MAIN();

My keyboard now works and everything else. However, the sprite will only move once every second. So I changed the install_int_ex(increment_speed_counter, BPS_TO_TIMER(1)) value from 1 to a higher number (10 and 60). Now the input is working perfectly correctly, but the timer in the top corner is now not displayed at all! Do you have any idea what could be causing this and how to fix it?

Also, I realize that my code really is horrible. At this stage though, all I am trying to do is to get something actually working (undoubtedly terrible practice I'm sure) and go back and fix it up later. Or perhaps though, it would be better to start from scratch again and actually do a decent job of my code this time?

Once again, thanks for your help.

Kris Asick
Member #1,424
July 2001

You're drawing your buffer bitmap too many times per frame. You only ever want to draw it to the screen once per loop. The way your code is above, to achieve this, simply remove all your calls to draw_sprite(), acquire_screen() and release_screen(), make your blit call at the end of the loop encompass the entire screen (640 x 480) and you should be fine. Also, move your clear command to the top of your loop before you process speed_counter.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Reaper
Member #8,737
June 2007

Thank you for your help, but I'm not sure that I fully understand. Is this what you were meaning?

1int main()
2{
3 allegro_init();
4 install_keyboard();
5 set_color_depth(16);
6 set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
7 
8 setupGame();
9 
10 BITMAP *bmpBackBuffer = create_bitmap(640,480);
11 install_int_ex(increment_speed_counter, BPS_TO_TIMER(1)); //should this be 1 or 60?
12 int seccount = 0;
13 while (!key[KEY_ESC])
14 {
15 clear(bmpBackBuffer);
16 while (speed_counter > 0)
17 {
18 movePlayer();
19 seccount++;
20 speed_counter--;
21 }
22 textprintf_ex(bmpBackBuffer, font, 5, 5, makecol(255, 255, 255), 1, "Secs: %d", seccount);
23 blit(bmpBackBuffer,screen,0,0,0,0,640,480);
24 }
25 
26 return 0;
27}
28END_OF_MAIN();

The above code makes the screen flash once every second between a black screen with the counter on it, and the normal game screen. Everything else works but is their any way that I can stop this flashing? Thanks.

HardTranceFan
Member #7,317
June 2006
avatar

No. Keep the clear(bmpBackBuffer) where it was.

Your movePlayer() should only do that - move the player. It should have no draw_sprite() or blit() calls in it at all. This is so that you separate your game logic from your drawing.

You should have another function drawPlayer(BITMAP*) that draws the player to the screen. You want to call this function after you've cleared the buffer.

1...
2 while (!key[KEY_ESC])
3 {
4 while (speed_counter > 0)
5 {
6 movePlayer();
7 seccount++;
8 speed_counter--;
9 }
10 clear(bmpBackBuffer);
11 drawPlayer(bmpBackBuffer);
12 textprintf_ex(bmpBackBuffer, font, 5, 5, makecol(255, 255, 255), 1, "Secs: %d", seccount);
13 blit(bmpBackBuffer,screen,0,0,0,0,640,480);
14 }
15...

--
"Shame your mind don't shine like your possessions do" - Faithless (I want more part 1)

Kris Asick
Member #1,424
July 2001

I just noticed you have TWO buffers...

You only need one buffer, and all drawing should happen on it. When you're finished drawing everything, you simply blit the entire buffer to the screen.

Thus to fix your code as it is without any major changes, change all references to "buffer" to "bmpBackBuffer".

And HardTranceFan's advice is good, you should separate your rendering code from everything else so that it can all be grouped together, but until you do, leave the clear(bmpBackBuffer) command in its new spot. Worry about making it work first, then separate the rendering from everything else.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Reaper
Member #8,737
June 2007

Thank you all for all your assistance. Kris Asick, I think the having two buffers was causing a lot of the problems, as it is now working much better. Now I need to go about fixing up my code :-) - thank you for your ideas on how to begin this.

Thank you again.

Go to: