===== Allegro — Input ===== Cet article explique le fonction de l'Input clavier et souris. ===== Exemple basique d'Input souris ===== Basé sur l'exemple de l'article précédent, la //boite// suit la souris dans cet exemple. #include #include const float FPS = 60; const int SCREEN_W = 640; const int SCREEN_H = 480; const int BOUNCER_SIZE = 32; int main(int argc, char **argv) { ALLEGRO_DISPLAY *display = NULL; ALLEGRO_EVENT_QUEUE *event_queue = NULL; ALLEGRO_TIMER *timer = NULL; ALLEGRO_BITMAP *bouncer = NULL; float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0; float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0; bool redraw = true; if(!al_init()) { fprintf(stderr, "failed to initialize allegro!\n"); return -1; } if(!al_install_mouse()) { fprintf(stderr, "failed to initialize the mouse!\n"); return -1; } timer = al_create_timer(1.0 / FPS); if(!timer) { fprintf(stderr, "failed to create timer!\n"); return -1; } display = al_create_display(SCREEN_W, SCREEN_H); if(!display) { fprintf(stderr, "failed to create display!\n"); al_destroy_timer(timer); return -1; } bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE); if(!bouncer) { fprintf(stderr, "failed to create bouncer bitmap!\n"); al_destroy_display(display); al_destroy_timer(timer); return -1; } al_set_target_bitmap(bouncer); al_clear_to_color(al_map_rgb(255, 0, 255)); al_set_target_bitmap(al_get_backbuffer(display)); event_queue = al_create_event_queue(); if(!event_queue) { fprintf(stderr, "failed to create event_queue!\n"); al_destroy_bitmap(bouncer); al_destroy_display(display); al_destroy_timer(timer); return -1; } al_register_event_source(event_queue, al_get_display_event_source(display)); al_register_event_source(event_queue, al_get_timer_event_source(timer)); al_register_event_source(event_queue, al_get_mouse_event_source()); al_clear_to_color(al_map_rgb(0,0,0)); al_flip_display(); al_start_timer(timer); while(1) { ALLEGRO_EVENT ev; al_wait_for_event(event_queue, &ev); if(ev.type == ALLEGRO_EVENT_TIMER) { redraw = true; } else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } else if(ev.type == ALLEGRO_EVENT_MOUSE_AXES || ev.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY) { bouncer_x = ev.mouse.x; bouncer_y = ev.mouse.y; } else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { break; } if(redraw && al_is_event_queue_empty(event_queue)) { redraw = false; al_clear_to_color(al_map_rgb(0,0,0)); al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0); al_flip_display(); } } al_destroy_bitmap(bouncer); al_destroy_timer(timer); al_destroy_display(display); al_destroy_event_queue(event_queue); return 0; } ==== Détails ==== On ne détaille ici que les nouveautés. if(!al_install_mouse()) { fprintf(stderr, "failed to initialize the mouse!\n"); return -1; } Initialise la gestion de la souris. **al_install_mouse** renvoie false en cas d'échec, dans ce cas on quitte le programme. al_register_event_source(event_queue, al_get_mouse_event_source()); Dirige la source d'event de la souris vers notre queue d'events. Nécessaire pour obtenir les events liés à la souris. else if(ev.type == ALLEGRO_EVENT_MOUSE_AXES || ev.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY) { bouncer_x = ev.mouse.x; bouncer_y = ev.mouse.y; } Un event de type **ALLEGRO_EVENT_MOUSE_AXES** est généré sur un déplacement de la souris par l'utilisateur, et un event de type **ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY** est généré quand la souris entre dans notre display. Ici on met à jour la position de notre boite aux coordonnées de la souris. else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { break; } Termine le programme en cas d'appui sur n'importe quel bouton de la souris. C'était plutôt simple non? **ATTENTION !!** L'event source de la souris flood, pour éviter d'avoir un jeu qui lag, je recommande de vérifier que l'event queue est vide avant de faire l'affichage, ou mieux, d'utiliser deux event queues, une pour actualiser l'affichage et une autre qui gère l'input. avec un thread pour les exécuter en même temps. ===== Exemple basique d'Input clavier ===== Basé sur l'exemple de l'article précédent, la boite suit la direction selon les touches du clavier #include #include const float FPS = 60; const int SCREEN_W = 640; const int SCREEN_H = 480; const int BOUNCER_SIZE = 32; enum MYKEYS { KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT }; int main(int argc, char **argv) { ALLEGRO_DISPLAY *display = NULL; ALLEGRO_EVENT_QUEUE *event_queue = NULL; ALLEGRO_TIMER *timer = NULL; ALLEGRO_BITMAP *bouncer = NULL; float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0; float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0; bool key[4] = { false, false, false, false }; bool redraw = true; bool doexit = false; if(!al_init()) { fprintf(stderr, "failed to initialize allegro!\n"); return -1; } if(!al_install_keyboard()) { fprintf(stderr, "failed to initialize the keyboard!\n"); return -1; } timer = al_create_timer(1.0 / FPS); if(!timer) { fprintf(stderr, "failed to create timer!\n"); return -1; } display = al_create_display(SCREEN_W, SCREEN_H); if(!display) { fprintf(stderr, "failed to create display!\n"); al_destroy_timer(timer); return -1; } bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE); if(!bouncer) { fprintf(stderr, "failed to create bouncer bitmap!\n"); al_destroy_display(display); al_destroy_timer(timer); return -1; } al_set_target_bitmap(bouncer); al_clear_to_color(al_map_rgb(255, 0, 255)); al_set_target_bitmap(al_get_backbuffer(display)); event_queue = al_create_event_queue(); if(!event_queue) { fprintf(stderr, "failed to create event_queue!\n"); al_destroy_bitmap(bouncer); al_destroy_display(display); al_destroy_timer(timer); return -1; } al_register_event_source(event_queue, al_get_display_event_source(display)); al_register_event_source(event_queue, al_get_timer_event_source(timer)); al_register_event_source(event_queue, al_get_keyboard_event_source()); al_clear_to_color(al_map_rgb(0,0,0)); al_flip_display(); al_start_timer(timer); while(!doexit) { ALLEGRO_EVENT ev; al_wait_for_event(event_queue, &ev); if(ev.type == ALLEGRO_EVENT_TIMER) { if(key[KEY_UP] && bouncer_y >= 4.0) { bouncer_y -= 4.0; } if(key[KEY_DOWN] && bouncer_y <= SCREEN_H - BOUNCER_SIZE - 4.0) { bouncer_y += 4.0; } if(key[KEY_LEFT] && bouncer_x >= 4.0) { bouncer_x -= 4.0; } if(key[KEY_RIGHT] && bouncer_x <= SCREEN_W - BOUNCER_SIZE - 4.0) { bouncer_x += 4.0; } redraw = true; } else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) { switch(ev.keyboard.keycode) { case ALLEGRO_KEY_UP: key[KEY_UP] = true; break; case ALLEGRO_KEY_DOWN: key[KEY_DOWN] = true; break; case ALLEGRO_KEY_LEFT: key[KEY_LEFT] = true; break; case ALLEGRO_KEY_RIGHT: key[KEY_RIGHT] = true; break; } } else if(ev.type == ALLEGRO_EVENT_KEY_UP) { switch(ev.keyboard.keycode) { case ALLEGRO_KEY_UP: key[KEY_UP] = false; break; case ALLEGRO_KEY_DOWN: key[KEY_DOWN] = false; break; case ALLEGRO_KEY_LEFT: key[KEY_LEFT] = false; break; case ALLEGRO_KEY_RIGHT: key[KEY_RIGHT] = false; break; case ALLEGRO_KEY_ESCAPE: doexit = true; break; } } if(redraw && al_is_event_queue_empty(event_queue)) { redraw = false; al_clear_to_color(al_map_rgb(0,0,0)); al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0); al_flip_display(); } } al_destroy_bitmap(bouncer); al_destroy_timer(timer); al_destroy_display(display); al_destroy_event_queue(event_queue); return 0; } ==== Détails ==== enum MYKEYS { KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT }; On définit nous-même ces constantes des touches qu'on utilisera dans le tableau des status des touches. bool key[4] = { false, false, false, false }; C'est notre tableau des status des touches, dans lequel on stockera le status des touches qui nous intéresse. bool doexit = false; Cette variable pour court-circuiter notre boucle While. if(!al_install_keyboard()) { fprintf(stderr, "failed to initialize the keyboard!\n"); return -1; } Initialise la gestion du clavier. **al_install_keyboard** retourne false en cas d'échec, on termine le programme si ça arrive. al_register_event_source(event_queue, al_get_keyboard_event_source()); Dirige la source d'event du clavier vers notre queue d'events. Nécessaire pour obtenir les events liés au clavier. while(!doexit) Permet de sortie de la boucle while dès que **doexit** passe à true. Une manière simple de quitter. if(key[KEY_UP] && bouncer_y >= 4.0) { bouncer_y -= 4.0; } if(key[KEY_DOWN] && bouncer_y <= SCREEN_H - BOUNCER_SIZE - 4.0) { bouncer_y += 4.0; } if(key[KEY_LEFT] && bouncer_x >= 4.0) { bouncer_x -= 4.0; } if(key[KEY_RIGHT] && bouncer_x <= SCREEN_W - BOUNCER_SIZE - 4.0) { bouncer_x += 4.0; } On vérifie si l'une de nos touches a été pressée, et on déplace notre boite dans la direction voulue. Pour économiser un peu de place et d'efforts, To save a bit of space and effort, we're going to go through both key events in parallel. else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) { Un event de type **ALLEGRO_EVENT_KEY_DOWN** est généré quand une touche est pressée. else if(ev.type == ALLEGRO_EVENT_KEY_UP) { Un event de type **ALLEGRO_EVENT_KEY_UP** est généré quand une touche est relachée. switch(ev.keyboard.keycode) { On switch sur le membre **keycode** de la structure keyboard event. **keycode** contient un entier de la cartographie clavier d'allegro. case ALLEGRO_KEY_*: key[KEY_*] = true; || key[KEY_*] = false; break; Dans les deux types d'event reçus, on stocke l'état de la touche dans notre tableau **key[]**. case ALLEGRO_KEY_ESC: doexit = true; break; Ici on passe **doexit** à true pour terminer la boucle au prochain tour. Un peu plus long que l'exemple sur la souris, mais tout aussi simple. [[allegro:bitmaps|Précédent]] << [[allegro:start#articles|Sommaire]] >> [[allegro:threads|Suivant]]