Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Getting keystrokes for display high scores

This thread is locked; no one can reply to it. rss feed Print
Getting keystrokes for display high scores
Eric Johnson
Member #14,841
January 2013
avatar

Hey there. Is there a better way to get the key a user typed and save it to a string than to use al_keycode_to_name? As a test, I want to create a high score table that saves the user's name. This is what I've got so far:

#SelectExpand
1#include <string> 2#include <iostream> 3 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_font.h> 6 7using std::cout; 8using std::string; 9 10void checkReturn(const bool condition) { 11 12 if (!condition) { 13 14 cout << "Error: something failed.\n"; 15 16 exit(EXIT_FAILURE); 17 } 18} 19 20int main(void) { 21 22 // Initialize Allegro and addons. 23 checkReturn(al_init()); 24 checkReturn(al_init_font_addon()); 25 checkReturn(al_install_keyboard()); 26 27 ALLEGRO_TIMER *timer; 28 ALLEGRO_DISPLAY *display; 29 ALLEGRO_EVENT_QUEUE *event_queue; 30 31 // Create events. 32 checkReturn((timer = al_create_timer(1.0 / 60.0))); 33 checkReturn((display = al_create_display(720, 480))); 34 checkReturn((event_queue = al_create_event_queue())); 35 36 // Register events. 37 al_register_event_source(event_queue, al_get_keyboard_event_source()); 38 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 39 al_register_event_source(event_queue, al_get_display_event_source(display)); 40 41 al_start_timer(timer); 42 43 bool render = true; 44 bool running = true; 45 46 // Whatever the user types will be saved to this string. 47 string name = ""; 48 49 // Use the built-in font, as it's easiest to use. 50 ALLEGRO_FONT *font = al_create_builtin_font(); 51 52 // Blow up the screen 500% to accommodate for the small font (above). 53 ALLEGRO_TRANSFORM transform; 54 al_identity_transform(&transform); 55 al_scale_transform(&transform, 5, 5); 56 al_use_transform(&transform); 57 58 while (running) { 59 60 ALLEGRO_EVENT event; 61 62 al_wait_for_event(event_queue, &event); 63 64 if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 65 66 // The window was closed; break the loop and end the program. 67 running = false; 68 } 69 else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { 70 71 switch (event.keyboard.keycode) { 72 73 case ALLEGRO_KEY_SPACE: 74 75 // Add a space to the string. 76 name += " "; 77 break; 78 79 case ALLEGRO_KEY_BACKSPACE: 80 81 if (name.length() > 0) { 82 83 // Remove the last character from the string. 84 name.erase(name.end() - 1, name.end()); 85 } 86 break; 87 88 default: 89 90 // Add whatever the user typed to the string. 91 name += al_keycode_to_name(event.keyboard.keycode); 92 break; 93 } 94 } 95 else if (event.type == ALLEGRO_EVENT_TIMER) { 96 97 render = true; 98 } 99 100 if (render && al_is_event_queue_empty(event_queue)) { 101 102 render = false; 103 104 al_clear_to_color(al_map_rgb(255, 255, 255)); 105 106 al_draw_text(font, al_map_rgb(255, 0, 0), 720 / 2 / 5, 16, ALLEGRO_ALIGN_CENTER, "What's your name?"); 107 108 // Draw text that user entered. 109 al_draw_textf(font, al_map_rgb(255, 0, 0), 720 / 2 / 5, 480 / 2 / 5, ALLEGRO_ALIGN_CENTER, "%s", name.c_str()); 110 111 al_flip_display(); 112 } 113 } 114 115 // Free up memory. 116 al_destroy_font(font); 117 al_destroy_timer(timer); 118 al_destroy_display(display); 119 al_destroy_event_queue(event_queue); 120 121 return 0; 122}

The above is self-explanatory, but it takes the user's keystrokes and saves it to a string named "name", then displays it as the user types. The problem with the above, however, is that it saves shift keys and caps lock (and others) as "SHIFT_*" and "CAPS_LOCK", which isn't what I want.

What's a better way to just get alphanumeric input and to ignore all the rest without writing a bunch of if statements to continue for each?

Thanks in advance. :)

Edgar Reynaldo
Member #8,592
May 2007
avatar

Monitor the event queue for ALLEGRO_EVENT_KEY_CHAR events and store their keycode in a string.

http://liballeg.org/a5docs/trunk/events.html#allegro_event_key_char

http://liballeg.org/a5docs/trunk/keyboard.html#key-codes

http://liballeg.org

do {

   ALLEGRO_EVENT ev;
   al_wait_for_event(queue , &ev);
   if (ev.type == ALLEGRO_EVENT_KEY_CHAR) {
      if (ev.keyboard.keycode >= ALLEGRO_KEY_A && ev.keyboard.keycode <= ALLEGRO_KEY_Z) {
          name += 'a' += (ev.keyboard.keycode - ALLEGRO_KEY_A);
      }
      if (ev.keyboard.keycode >= ALLEGRO_KEY_0 && ev.keyboard.keycode <= ALLEGRO_KEY_9) {
          name += '0' + (ev.keyboard.keycode - ALLEGRO_KEY_0)
      }
   }

} while (!al_is_event_queue_empty(queue));

Eric Johnson
Member #14,841
January 2013
avatar

That worked like a charm, Edgar. Thanks a bunch. :D

Could you explain the significance of 'a' and '0'? I noticed that changing 'a' to 'A' results in capturing the upper-case version of letters. Does this have something to do with encoding the characters?

torhu
Member #2,727
September 2002
avatar

A character literal is just a number ;)

Edgar Reynaldo
Member #8,592
May 2007
avatar

A traditional 'char' literal is just an ASCII number from -128 to 127. I'm taking advantage of the fact that the distance between ev.keyboard.keycode and ALLEGRO_KEY_A and ALLEGRO_KEY_0 is the same as the distance between 'a' and the character pressed and '0' and the character pressed.

ASCII chart :
Click Me!

Eric Johnson
Member #14,841
January 2013
avatar

Wow, that's slick! :o Thanks a bunch!

Go to: