Keyboard Interrupting on Mouse Positions?
PedroNexus

I am making a simple game using C and Allegro 5. I am currently hiding the mouse and swapping it for a custom mouse icon. The cursor icon's position is altered whenever a mouse movement is detected, then that mouse position is passed to variables mouse_x and mouse_y.

What bothers me is that if, for example, I have my mouse cursor at coordinates mouse_x = 100 and mouse_y = 200, and I press any key on the keyboard, the mouse cursor is shown both on the correct mouse_x and mouse_y coordinates AND two completely random y and x variables at the same time. Once I stop holding the keyboard's key, the wrong cursor disappears.

I have no clue what happens, but whenever I uninstall the keyboard using al_uninstall_keyboard(), that error is gone.

This is my code:

#SelectExpand
1#include <stdio.h> 2#include <stdlib.h> 3#include <allegro5\allegro.h> 4#include <allegro5\allegro_image.h> 5#include <allegro5\allegro_primitives.h> 6#include <allegro5\allegro_audio.h> 7#include <allegro5\allegro_font.h> 8#include <allegro5\allegro_ttf.h> 9#include <allegro5\allegro_acodec.h> 10 11enum gameMode{menu, farmGame, stdend}; 12enum soil{normal, wet}; 13enum soil2{unplow, plow}; 14enum cropType{none, tomato}; 15 16typedef struct gDisp //game display 17{ 18 int width; 19 int height; 20 ALLEGRO_DISPLAY *display; 21}gDisp; 22 23typedef struct fCrop //farm crop 24{ 25 cropType crop; 26 ALLEGRO_TIMEOUT *waterNeed; 27 ALLEGRO_TIMEOUT *growth[4]; //Crop's growth time on all stages 28}fCrop; 29 30typedef struct fTile //farm tiles 31{ 32 int xpoint; 33 int ypoint; 34 int size; 35 soil ground; 36 soil2 ground2; 37 fCrop crop; 38}fTile; 39 40int main() 41{ 42 //Allegro Initialization Area 43 al_init(); 44 al_init_image_addon(); 45 al_init_primitives_addon(); 46 al_init_font_addon(); 47 al_init_ttf_addon(); 48 al_init_acodec_addon(); 49 50 //Allegro Installation Area 51 al_install_keyboard(); 52 al_install_mouse(); 53 54 //Allegro Variable Area 55 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue(); 56 ALLEGRO_EVENT ev; 57 ALLEGRO_FONT *font[3]; 58 59 //Allegro Variable Declaration Area 60 61 //My Enums Area 62 gameMode gamemode = menu; 63 ALLEGRO_BITMAP *bmp[30]; //20-30: Menu Bitmaps 64 ALLEGRO_BITMAP *ico; 65 66 //My Structs Area 67 gDisp disp; 68 disp = {0, 0, NULL}; 69 70 //Games... Here we go! 71 if (gamemode == menu) 72 { 73 char *currgamelist[4] = { "PLAY", "TUTORIAL", "CREDITS" }; 74 disp.width = 600, disp.height = 600, disp.display = al_create_display(disp.width, disp.height); 75 ico = al_load_bitmap("tomato_seedbase.png"); 76 bmp[0] = al_load_bitmap("Normal-select.png"); 77 bmp[1] = al_load_bitmap("Link-select.png"); 78 al_set_window_title(disp.display, "Farming Hero"); 79 al_set_display_icon(disp.display, ico); 80 al_hide_mouse_cursor(disp.display); 81 font[0] = al_load_font("PressStart2P.ttf", 32, 0); 82 al_clear_to_color(al_map_rgb(0, 0, 0)); 83 al_register_event_source(queue, al_get_mouse_event_source()); 84 al_register_event_source(queue, al_get_keyboard_event_source()); 85 int mouse_x; 86 int mouse_y; 87 while (gamemode == menu) 88 { 89 al_wait_for_event(queue, &ev); 90 al_clear_to_color(al_map_rgb(0, 0, 0)); 91 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 92 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 93 { 94 al_destroy_display(disp.display); 95 al_destroy_font(font[0]); 96 return 0; 97 } 98 al_draw_text(font[0], al_map_rgb(255, 255, 255), 105, 50, 0, "FARMING HERO"); 99 al_draw_text(font[0], al_map_rgb(255, 255, 255), 30, 200, 0, currgamelist[0]); 100 al_draw_text(font[0], al_map_rgb(255, 255, 255), 30, 300, 0, currgamelist[1]); 101 al_draw_text(font[0], al_map_rgb(255, 255, 255), 30, 400, 0, currgamelist[2]); 102 al_draw_text(font[0], al_map_rgb(255, 255, 255), 30, 500, 0, "EXIT"); 103 al_draw_text(font[0], al_map_rgb(255, 255, 255), 30, 500, 0, " "); 104 if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 105 if (ev.mouse.button & 1) 106 { 107 if (ev.mouse.x >= 30 && ev.mouse.y >= 200 && ev.mouse.x <= al_get_text_width(font[0], currgamelist[0]) + 30 && ev.mouse.y <= 232) 108 gamemode = farmGame; 109 if (ev.mouse.x >= 30 && ev.mouse.y >= 300 && ev.mouse.x <= al_get_text_width(font[0], currgamelist[1]) + 30 && ev.mouse.y <= 332) 110 al_destroy_display(disp.display), al_destroy_font(font[0]), exit(0); 111 if (ev.mouse.x >= 30 && ev.mouse.y >= 400 && ev.mouse.x <= al_get_text_width(font[0], currgamelist[2]) + 30 && ev.mouse.y <= 432) 112 al_destroy_display(disp.display), al_destroy_font(font[0]), exit(0); 113 if (ev.mouse.x >= 30 && ev.mouse.y >= 500 && ev.mouse.x <= al_get_text_width(font[0], "EXIT") + 30 && ev.mouse.y <= 532) 114 al_destroy_display(disp.display), al_destroy_font(font[0]), exit(0); 115 } 116 if (ev.type == ALLEGRO_EVENT_MOUSE_AXES) 117 mouse_x = ev.mouse.x, mouse_y = ev.mouse.y; 118 if (mouse_x >= 30 && mouse_x <= al_get_text_width(font[0], currgamelist[0]) + 30 && mouse_y >= 195 && mouse_y <= 235) 119 al_draw_text(font[0], al_map_rgb(255, 239, 0), 30, 200, 0, currgamelist[0]), al_draw_bitmap(bmp[1], mouse_x, mouse_y, 0); 120 else if (mouse_x >= 30 && mouse_x <= al_get_text_width(font[0], currgamelist[1]) + 30 && mouse_y >= 295 && mouse_y <= 335) 121 al_draw_text(font[0], al_map_rgb(255, 239, 0), 30, 300, 0, currgamelist[1]), al_draw_bitmap(bmp[1], mouse_x, mouse_y, 0); 122 else if (mouse_x >= 30 && mouse_x <= al_get_text_width(font[0], currgamelist[2]) + 30 && mouse_y >= 395 && mouse_y <= 435) 123 al_draw_text(font[0], al_map_rgb(255, 239, 0), 30, 400, 0, currgamelist[2]), al_draw_bitmap(bmp[1], mouse_x, mouse_y, 0); 124 else if (mouse_x >= 30 && mouse_x <= al_get_text_width(font[0], "EXIT") + 30 && mouse_y >= 495 && mouse_y <= 535) 125 al_draw_text(font[0], al_map_rgb(255, 239, 0), 30, 500, 0, "EXIT"), al_draw_bitmap(bmp[1], mouse_x, mouse_y, 0); 126 else{ al_draw_bitmap(bmp[0], mouse_x, mouse_y, 0); }; 127 al_flip_display(); 128 } 129 } 130 if (gamemode == farmGame) 131 { 132 ALLEGRO_TIMER *fps = al_create_timer(1.00 / 60.00); 133 font[0] = al_load_font("PressStart2P.ttf", 8, 0); 134 font[1] = al_load_font("PressStart2P.ttf", 16, 0); 135 al_register_event_source(queue, al_get_timer_event_source(fps)); 136 int mouse_x, mouse_y; 137 mouse_x = -50, mouse_y = 0; 138 fCrop empty = { none, 0, 0 }; 139 fTile tile[100]; 140 int x_prep, y_prep; //prepare the tile's configuration 141 x_prep = 0, y_prep = 0; 142 for (int i = 0; i < 100; i++) 143 { 144 if (x_prep == 10) 145 x_prep = 0, y_prep++; 146 tile[i] = { x_prep, y_prep, 51, normal, unplow, empty}; 147 x_prep++; 148 } 149 al_clear_to_color(al_map_rgb(0, 0, 0)); 150 al_flip_display(); 151 bmp[0] = al_load_bitmap("link-select.png"); 152 bmp[1] = al_load_bitmap("ground_normal.png"); 153 bmp[9] = al_create_bitmap(disp.width, disp.height); 154 bmp[30] = al_load_bitmap("tomato_seedbase.png"); 155 al_uninstall_keyboard(); 156 al_start_timer(fps); 157 al_set_target_bitmap(bmp[9]); 158 al_draw_filled_rectangle(512, 2, disp.width - 2, 508, al_map_rgb(150, 120, 0)); 159 al_draw_filled_rectangle(2, 512, 512, disp.height - 2, al_map_rgb(150, 120, 0)); 160 al_draw_filled_rectangle(512, 512, disp.width - 2, disp.height - 2, al_map_rgb(150, 120, 0)); 161 al_draw_rectangle(512, 2, disp.width - 2, 511, al_map_rgb(70, 50, 0), 5); 162 al_draw_rectangle(2, 512, 512, disp.height - 2, al_map_rgb(70, 50, 0), 5); 163 al_draw_rectangle(512, 512, disp.width - 2, disp.height - 2, al_map_rgb(70, 50, 0), 5); 164 al_set_target_backbuffer(disp.display); 165 while (gamemode == farmGame) 166 { 167 char tileinfo[5][15]; 168 al_clear_to_color(al_map_rgb(0, 0, 0)); 169 al_wait_for_event(queue, &ev); 170 for (int i = 0; i < 100; i++) 171 { 172 if (tile[i].ground == normal && tile[i].ground2 == unplow) 173 al_draw_bitmap(bmp[1], tile[i].xpoint * tile[i].size, tile[i].ypoint * tile[i].size, 0); 174 if (mouse_x >= 0 && mouse_x <= 508 && mouse_y >= 0 && mouse_y <= 508) 175 if (mouse_x >= tile[i].xpoint * tile[i].size && mouse_x <= tile[i].xpoint * tile[i].size + tile[i].size && mouse_y >= tile[i].ypoint * tile[i].size && mouse_y <= tile[i].ypoint * tile[i].size + tile[i].size) 176 { 177 tile[i].crop.crop == none ? strcpy(tileinfo[1], "NONE") : 0, tile[i].crop.crop == tomato ? strcpy(tileinfo[1], "TOMATOES") : 0; 178 tile[i].ground == normal ? strcpy(tileinfo[2], "DRY") : 0, tile[i].ground == wet ? strcpy(tileinfo[2], "WET") : 0; 179 tile[i].ground2 == unplow ? strcpy(tileinfo[3], "UNPLOW") : 0, tile[i].ground2 == plow ? strcpy(tileinfo[3], "PLOW") : 0; 180 } 181 } 182 al_draw_bitmap(bmp[0], ev.mouse.x, ev.mouse.y, 0); 183 if (ev.type == ALLEGRO_EVENT_MOUSE_AXES) 184 mouse_x = ev.mouse.x, mouse_y = ev.mouse.y; 185 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 186 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 187 gamemode = stdend; 188 al_draw_bitmap(bmp[9], 0, 0, 0); 189 if (mouse_x >= 503 && mouse_x <= disp.height && mouse_y >= 10 && mouse_y <= al_get_bitmap_height(bmp[30])) 190 al_draw_tinted_bitmap(bmp[30], al_map_rgb(125, 255, 37), 503, 10, 0), al_draw_text(font[1], al_map_rgb(125, 255, 37), 525, 100, 0, "SHOP"); 191 else{ al_draw_bitmap(bmp[30], 503, 10, 0), al_draw_text(font[1], al_map_rgb(255, 255, 255), 525, 100, 0, "SHOP"); } 192 if (tileinfo[1] != NULL && tileinfo[2] != NULL && tileinfo[3] != NULL) 193 { 194 al_draw_textf(font[0], al_map_rgb(255, 255, 255), 520, 520, 0, "%s", tileinfo[1]); 195 al_draw_textf(font[0], al_map_rgb(255, 255, 255), 520, 550, 0, "%s", tileinfo[2]); 196 al_draw_textf(font[0], al_map_rgb(255, 255, 255), 520, 580, 0, "%s", tileinfo[3]); 197 } 198 al_draw_bitmap(bmp[0], mouse_x, mouse_y, 0); 199 al_flip_display(); 200 } 201 } 202 if (gamemode == stdend) 203 { 204 al_rest(2); 205 al_destroy_display(disp.display); 206 } 207 return 0; 208}

Edgar Reynaldo

If you attach a zip file of your source code and all necessary resources, I will test it for you, and see if the same thing happens for me.

What version of Allegro 5 are you using? 5.2 is the latest version.

Actually nevermind. I think I see what is wrong. Scroll down and look at the two highlighted lines.

#SelectExpand
1 if (gamemode == farmGame) 2 { 3 ALLEGRO_TIMER *fps = al_create_timer(1.00 / 60.00); 4 font[0] = al_load_font("PressStart2P.ttf", 8, 0); 5 font[1] = al_load_font("PressStart2P.ttf", 16, 0); 6 al_register_event_source(queue, al_get_timer_event_source(fps)); 7 int mouse_x, mouse_y; 8 mouse_x = -50, mouse_y = 0; 9 fCrop empty = { none, 0, 0 }; 10 fTile tile[100]; 11 int x_prep, y_prep; //prepare the tile's configuration 12 x_prep = 0, y_prep = 0; 13 for (int i = 0; i < 100; i++) 14 { 15 if (x_prep == 10) 16 x_prep = 0, y_prep++; 17 tile[i] = { x_prep, y_prep, 51, normal, unplow, empty}; 18 x_prep++; 19 } 20 al_clear_to_color(al_map_rgb(0, 0, 0)); 21 al_flip_display(); 22 bmp[0] = al_load_bitmap("link-select.png"); 23 bmp[1] = al_load_bitmap("ground_normal.png"); 24 bmp[9] = al_create_bitmap(disp.width, disp.height); 25 bmp[30] = al_load_bitmap("tomato_seedbase.png"); 26 al_uninstall_keyboard(); 27 al_start_timer(fps); 28 al_set_target_bitmap(bmp[9]); 29 al_draw_filled_rectangle(512, 2, disp.width - 2, 508, al_map_rgb(150, 120, 0)); 30 al_draw_filled_rectangle(2, 512, 512, disp.height - 2, al_map_rgb(150, 120, 0)); 31 al_draw_filled_rectangle(512, 512, disp.width - 2, disp.height - 2, al_map_rgb(150, 120, 0)); 32 al_draw_rectangle(512, 2, disp.width - 2, 511, al_map_rgb(70, 50, 0), 5); 33 al_draw_rectangle(2, 512, 512, disp.height - 2, al_map_rgb(70, 50, 0), 5); 34 al_draw_rectangle(512, 512, disp.width - 2, disp.height - 2, al_map_rgb(70, 50, 0), 5); 35 al_set_target_backbuffer(disp.display); 36 while (gamemode == farmGame) 37 { 38 char tileinfo[5][15]; 39 al_clear_to_color(al_map_rgb(0, 0, 0)); 40 al_wait_for_event(queue, &ev); 41 for (int i = 0; i < 100; i++) 42 { 43 if (tile[i].ground == normal && tile[i].ground2 == unplow) 44 al_draw_bitmap(bmp[1], tile[i].xpoint * tile[i].size, tile[i].ypoint * tile[i].size, 0); 45 if (mouse_x >= 0 && mouse_x <= 508 && mouse_y >= 0 && mouse_y <= 508) 46 if (mouse_x >= tile[i].xpoint * tile[i].size && mouse_x <= tile[i].xpoint * tile[i].size + tile[i].size && mouse_y >= tile[i].ypoint * tile[i].size && mouse_y <= tile[i].ypoint * tile[i].size + tile[i].size) 47 { 48 tile[i].crop.crop == none ? strcpy(tileinfo[1], "NONE") : 0, tile[i].crop.crop == tomato ? strcpy(tileinfo[1], "TOMATOES") : 0; 49 tile[i].ground == normal ? strcpy(tileinfo[2], "DRY") : 0, tile[i].ground == wet ? strcpy(tileinfo[2], "WET") : 0; 50 tile[i].ground2 == unplow ? strcpy(tileinfo[3], "UNPLOW") : 0, tile[i].ground2 == plow ? strcpy(tileinfo[3], "PLOW") : 0; 51 } 52 }
53 al_draw_bitmap(bmp[0], ev.mouse.x, ev.mouse.y, 0);
54 if (ev.type == ALLEGRO_EVENT_MOUSE_AXES) 55 mouse_x = ev.mouse.x, mouse_y = ev.mouse.y; 56 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 57 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 58 gamemode = stdend; 59 al_draw_bitmap(bmp[9], 0, 0, 0); 60 if (mouse_x >= 503 && mouse_x <= disp.height && mouse_y >= 10 && mouse_y <= al_get_bitmap_height(bmp[30])) 61 al_draw_tinted_bitmap(bmp[30], al_map_rgb(125, 255, 37), 503, 10, 0), al_draw_text(font[1], al_map_rgb(125, 255, 37), 525, 100, 0, "SHOP"); 62 else{ al_draw_bitmap(bmp[30], 503, 10, 0), al_draw_text(font[1], al_map_rgb(255, 255, 255), 525, 100, 0, "SHOP"); } 63 if (tileinfo[1] != NULL && tileinfo[2] != NULL && tileinfo[3] != NULL) 64 { 65 al_draw_textf(font[0], al_map_rgb(255, 255, 255), 520, 520, 0, "%s", tileinfo[1]); 66 al_draw_textf(font[0], al_map_rgb(255, 255, 255), 520, 550, 0, "%s", tileinfo[2]); 67 al_draw_textf(font[0], al_map_rgb(255, 255, 255), 520, 580, 0, "%s", tileinfo[3]); 68 }
69 al_draw_bitmap(bmp[0], mouse_x, mouse_y, 0);
70 al_flip_display(); 71 } 72 }

You're drawing the mouse twice. The reason it moves when you press a key is because you are reading ev.mouse.x and ev.mouse.y from a keyboard event. You need to make sure it is a mouse event before you alter mouse_x and mouse_y.

You should add in a timer, and only perform your logic when the timer ticks. Separate drawing and logic. That is part of your problem.

Thread #616216. Printed from Allegro.cc