docs/html/guideinputkeyboard.html
changeset 3352 6dc250ebdd80
parent 3351 8e0182c236d8
child 3353 6b14223dd5c7
equal deleted inserted replaced
3351:8e0182c236d8 3352:6dc250ebdd80
     1 <HTML
       
     2 ><HEAD
       
     3 ><TITLE
       
     4 >Handling the Keyboard</TITLE
       
     5 ><META
       
     6 NAME="GENERATOR"
       
     7 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
       
     8 "><LINK
       
     9 REL="HOME"
       
    10 TITLE="SDL Library Documentation"
       
    11 HREF="index.html"><LINK
       
    12 REL="UP"
       
    13 TITLE="Input handling"
       
    14 HREF="guideinput.html"><LINK
       
    15 REL="PREVIOUS"
       
    16 TITLE="Input handling"
       
    17 HREF="guideinput.html"><LINK
       
    18 REL="NEXT"
       
    19 TITLE="Examples"
       
    20 HREF="guideexamples.html"></HEAD
       
    21 ><BODY
       
    22 CLASS="SECT1"
       
    23 BGCOLOR="#FFF8DC"
       
    24 TEXT="#000000"
       
    25 LINK="#0000ee"
       
    26 VLINK="#551a8b"
       
    27 ALINK="#ff0000"
       
    28 ><DIV
       
    29 CLASS="NAVHEADER"
       
    30 ><TABLE
       
    31 SUMMARY="Header navigation table"
       
    32 WIDTH="100%"
       
    33 BORDER="0"
       
    34 CELLPADDING="0"
       
    35 CELLSPACING="0"
       
    36 ><TR
       
    37 ><TH
       
    38 COLSPAN="3"
       
    39 ALIGN="center"
       
    40 >SDL Library Documentation</TH
       
    41 ></TR
       
    42 ><TR
       
    43 ><TD
       
    44 WIDTH="10%"
       
    45 ALIGN="left"
       
    46 VALIGN="bottom"
       
    47 ><A
       
    48 HREF="guideinput.html"
       
    49 ACCESSKEY="P"
       
    50 >Prev</A
       
    51 ></TD
       
    52 ><TD
       
    53 WIDTH="80%"
       
    54 ALIGN="center"
       
    55 VALIGN="bottom"
       
    56 >Chapter 3. Input handling</TD
       
    57 ><TD
       
    58 WIDTH="10%"
       
    59 ALIGN="right"
       
    60 VALIGN="bottom"
       
    61 ><A
       
    62 HREF="guideexamples.html"
       
    63 ACCESSKEY="N"
       
    64 >Next</A
       
    65 ></TD
       
    66 ></TR
       
    67 ></TABLE
       
    68 ><HR
       
    69 ALIGN="LEFT"
       
    70 WIDTH="100%"></DIV
       
    71 ><DIV
       
    72 CLASS="SECT1"
       
    73 ><H1
       
    74 CLASS="SECT1"
       
    75 ><A
       
    76 NAME="GUIDEINPUTKEYBOARD"
       
    77 ></A
       
    78 >Handling the Keyboard</H1
       
    79 ><DIV
       
    80 CLASS="SECT2"
       
    81 ><H2
       
    82 CLASS="SECT2"
       
    83 ><A
       
    84 NAME="AEN271"
       
    85 ></A
       
    86 >Keyboard Related Structures</H2
       
    87 ><P
       
    88 >It should make it a lot easier to understand this tutorial is you are familiar with the data types involved in keyboard access, so I'll explain them first.</P
       
    89 ><DIV
       
    90 CLASS="SECT3"
       
    91 ><H3
       
    92 CLASS="SECT3"
       
    93 ><A
       
    94 NAME="AEN274"
       
    95 ></A
       
    96 >SDLKey</H3
       
    97 ><P
       
    98 ><SPAN
       
    99 CLASS="STRUCTNAME"
       
   100 >SDLKey</SPAN
       
   101 > is an enumerated type defined in SDL/include/SDL_keysym.h and detailed <A
       
   102 HREF="sdlkey.html"
       
   103 >here</A
       
   104 >. Each <SPAN
       
   105 CLASS="STRUCTNAME"
       
   106 >SDLKey</SPAN
       
   107 > symbol represents a key, <TT
       
   108 CLASS="LITERAL"
       
   109 >SDLK_a</TT
       
   110 > corresponds to the 'a' key on a keyboard, <TT
       
   111 CLASS="LITERAL"
       
   112 >SDLK_SPACE</TT
       
   113 > corresponds to the space bar, and so on.</P
       
   114 ></DIV
       
   115 ><DIV
       
   116 CLASS="SECT3"
       
   117 ><H3
       
   118 CLASS="SECT3"
       
   119 ><A
       
   120 NAME="AEN282"
       
   121 ></A
       
   122 >SDLMod</H3
       
   123 ><P
       
   124 >SDLMod is an enumerated type, similar to <SPAN
       
   125 CLASS="STRUCTNAME"
       
   126 >SDLKey</SPAN
       
   127 >, however it enumerates keyboard modifiers (Control, Alt, Shift). The full list of modifier symbols is <A
       
   128 HREF="sdlkey.html#SDLMOD"
       
   129 >here</A
       
   130 >. <SPAN
       
   131 CLASS="STRUCTNAME"
       
   132 >SDLMod</SPAN
       
   133 > values can be AND'd together to represent several modifiers.</P
       
   134 ></DIV
       
   135 ><DIV
       
   136 CLASS="SECT3"
       
   137 ><H3
       
   138 CLASS="SECT3"
       
   139 ><A
       
   140 NAME="AEN288"
       
   141 ></A
       
   142 >SDL_keysym</H3
       
   143 ><PRE
       
   144 CLASS="PROGRAMLISTING"
       
   145 >typedef struct{
       
   146   Uint8 scancode;
       
   147   SDLKey sym;
       
   148   SDLMod mod;
       
   149   Uint16 unicode;
       
   150 } SDL_keysym;</PRE
       
   151 ><P
       
   152 >The <SPAN
       
   153 CLASS="STRUCTNAME"
       
   154 >SDL_keysym</SPAN
       
   155 > structure describes a key press or a key release. The <TT
       
   156 CLASS="STRUCTFIELD"
       
   157 ><I
       
   158 >scancode</I
       
   159 ></TT
       
   160 > field is hardware specific and should be ignored unless you know what your doing. The <TT
       
   161 CLASS="STRUCTFIELD"
       
   162 ><I
       
   163 >sym</I
       
   164 ></TT
       
   165 > field is the <SPAN
       
   166 CLASS="STRUCTNAME"
       
   167 >SDLKey</SPAN
       
   168 > value of the key being pressed or released. The <TT
       
   169 CLASS="STRUCTFIELD"
       
   170 ><I
       
   171 >mod</I
       
   172 ></TT
       
   173 > field describes the state of the keyboard modifiers at the time the key press or release occurred. So a value of <TT
       
   174 CLASS="LITERAL"
       
   175 >KMOD_NUM | KMOD_CAPS | KMOD_LSHIFT</TT
       
   176 > would mean that Numlock, Capslock and the left shift key were all press (or enabled in the case of the lock keys). Finally, the <TT
       
   177 CLASS="STRUCTFIELD"
       
   178 ><I
       
   179 >unicode</I
       
   180 ></TT
       
   181 > field stores the 16-bit unicode value of the key.</P
       
   182 ><DIV
       
   183 CLASS="NOTE"
       
   184 ><BLOCKQUOTE
       
   185 CLASS="NOTE"
       
   186 ><P
       
   187 ><B
       
   188 >Note: </B
       
   189 >It should be noted and understood that this field is only valid when the <SPAN
       
   190 CLASS="STRUCTNAME"
       
   191 >SDL_keysym</SPAN
       
   192 > is describing a key press, not a key release. Unicode values only make sense on a key press because the unicode value describes an international character and only key presses produce characters. More information on Unicode can be found at <A
       
   193 HREF="http://www.unicode.org"
       
   194 TARGET="_top"
       
   195 >www.unicode.org</A
       
   196 ></P
       
   197 ></BLOCKQUOTE
       
   198 ></DIV
       
   199 ><DIV
       
   200 CLASS="NOTE"
       
   201 ><BLOCKQUOTE
       
   202 CLASS="NOTE"
       
   203 ><P
       
   204 ><B
       
   205 >Note: </B
       
   206 >Unicode translation must be enabled using the <A
       
   207 HREF="sdlenableunicode.html"
       
   208 ><TT
       
   209 CLASS="FUNCTION"
       
   210 >SDL_EnableUNICODE</TT
       
   211 ></A
       
   212 > function.</P
       
   213 ></BLOCKQUOTE
       
   214 ></DIV
       
   215 ></DIV
       
   216 ><DIV
       
   217 CLASS="SECT3"
       
   218 ><H3
       
   219 CLASS="SECT3"
       
   220 ><A
       
   221 NAME="AEN307"
       
   222 ></A
       
   223 >SDL_KeyboardEvent</H3
       
   224 ><PRE
       
   225 CLASS="PROGRAMLISTING"
       
   226 >typedef struct{
       
   227   Uint8 type;
       
   228   Uint8 state;
       
   229   SDL_keysym keysym;
       
   230 } SDL_KeyboardEvent;</PRE
       
   231 ><P
       
   232 >The <SPAN
       
   233 CLASS="STRUCTNAME"
       
   234 >SDL_KeyboardEvent</SPAN
       
   235 > describes a keyboard event (obviously). The <TT
       
   236 CLASS="STRUCTFIELD"
       
   237 ><I
       
   238 >key</I
       
   239 ></TT
       
   240 > member of the <A
       
   241 HREF="sdlevent.html"
       
   242 ><SPAN
       
   243 CLASS="STRUCTNAME"
       
   244 >SDL_Event</SPAN
       
   245 ></A
       
   246 > union is a <SPAN
       
   247 CLASS="STRUCTNAME"
       
   248 >SDL_KeyboardEvent</SPAN
       
   249 > structure. The <TT
       
   250 CLASS="STRUCTFIELD"
       
   251 ><I
       
   252 >type</I
       
   253 ></TT
       
   254 > field specifies whether the event is a key release (<TT
       
   255 CLASS="LITERAL"
       
   256 >SDL_KEYUP</TT
       
   257 >) or a key press (<TT
       
   258 CLASS="LITERAL"
       
   259 >SDL_KEYDOWN</TT
       
   260 >) event. The <TT
       
   261 CLASS="STRUCTFIELD"
       
   262 ><I
       
   263 >state</I
       
   264 ></TT
       
   265 > is largely redundant, it reports the same information as the <TT
       
   266 CLASS="STRUCTFIELD"
       
   267 ><I
       
   268 >type</I
       
   269 ></TT
       
   270 > field but uses different values (<TT
       
   271 CLASS="LITERAL"
       
   272 >SDL_RELEASED</TT
       
   273 > and <TT
       
   274 CLASS="LITERAL"
       
   275 >SDL_PRESSED</TT
       
   276 >). The <TT
       
   277 CLASS="STRUCTFIELD"
       
   278 ><I
       
   279 >keysym</I
       
   280 ></TT
       
   281 > contains information of the key press or release that this event represents (see above).</P
       
   282 ></DIV
       
   283 ></DIV
       
   284 ><DIV
       
   285 CLASS="SECT2"
       
   286 ><H2
       
   287 CLASS="SECT2"
       
   288 ><A
       
   289 NAME="AEN324"
       
   290 ></A
       
   291 >Reading Keyboard Events</H2
       
   292 ><P
       
   293 >Reading keybaord events from the event queue is quite simple (the event queue and using it is described <A
       
   294 HREF="sdlevent.html"
       
   295 >here</A
       
   296 >). We read events using <A
       
   297 HREF="sdlpollevent.html"
       
   298 ><TT
       
   299 CLASS="FUNCTION"
       
   300 >SDL_PollEvent</TT
       
   301 ></A
       
   302 > in a <TT
       
   303 CLASS="LITERAL"
       
   304 >while()</TT
       
   305 > loop and check for <TT
       
   306 CLASS="LITERAL"
       
   307 >SDL_KEYUP</TT
       
   308 > and <TT
       
   309 CLASS="LITERAL"
       
   310 >SDL_KEYDOWN</TT
       
   311 > events using a <TT
       
   312 CLASS="LITERAL"
       
   313 >switch</TT
       
   314 > statement, like so:</P
       
   315 ><DIV
       
   316 CLASS="EXAMPLE"
       
   317 ><A
       
   318 NAME="AEN334"
       
   319 ></A
       
   320 ><P
       
   321 ><B
       
   322 >Example 3-10. Reading Keyboard Events</B
       
   323 ></P
       
   324 ><PRE
       
   325 CLASS="PROGRAMLISTING"
       
   326 >  SDL_Event event;
       
   327   .
       
   328   .
       
   329   /* Poll for events. SDL_PollEvent() returns 0 when there are no  */
       
   330   /* more events on the event queue, our while loop will exit when */
       
   331   /* that occurs.                                                  */
       
   332   while( SDL_PollEvent( &#38;event ) ){
       
   333     /* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */
       
   334     switch( event.type ){
       
   335       case SDL_KEYDOWN:
       
   336         printf( "Key press detected\n" );
       
   337         break;
       
   338 
       
   339       case SDL_KEYUP:
       
   340         printf( "Key release detected\n" );
       
   341         break;
       
   342 
       
   343       default:
       
   344         break;
       
   345     }
       
   346   }
       
   347   .
       
   348   .</PRE
       
   349 ></DIV
       
   350 ><P
       
   351 >This is a very basic example. No information about the key press or release is interpreted. We will explore the other extreme out our first full example below - reporting all available information about a keyboard event.</P
       
   352 ></DIV
       
   353 ><DIV
       
   354 CLASS="SECT2"
       
   355 ><H2
       
   356 CLASS="SECT2"
       
   357 ><A
       
   358 NAME="AEN338"
       
   359 ></A
       
   360 >A More Detailed Look</H2
       
   361 ><P
       
   362 >Before we can read events SDL must be initialised with <A
       
   363 HREF="sdlinit.html"
       
   364 ><TT
       
   365 CLASS="FUNCTION"
       
   366 >SDL_Init</TT
       
   367 ></A
       
   368 > and a video mode must be set using <A
       
   369 HREF="sdlsetvideomode.html"
       
   370 ><TT
       
   371 CLASS="FUNCTION"
       
   372 >SDL_SetVideoMode</TT
       
   373 ></A
       
   374 >. There are, however, two other functions we must use to obtain all the information required. We must enable unicode translation by calling <TT
       
   375 CLASS="FUNCTION"
       
   376 >SDL_EnableUNICODE(1)</TT
       
   377 > and we must convert <SPAN
       
   378 CLASS="STRUCTNAME"
       
   379 >SDLKey</SPAN
       
   380 > values into something printable, using <A
       
   381 HREF="sdlgetkeyname.html"
       
   382 ><TT
       
   383 CLASS="FUNCTION"
       
   384 >SDL_GetKeyName</TT
       
   385 ></A
       
   386 ></P
       
   387 ><DIV
       
   388 CLASS="NOTE"
       
   389 ><BLOCKQUOTE
       
   390 CLASS="NOTE"
       
   391 ><P
       
   392 ><B
       
   393 >Note: </B
       
   394 >It is useful to note that unicode values &#60; 0x80 translate directly a characters ASCII value. THis is used in the example below</P
       
   395 ></BLOCKQUOTE
       
   396 ></DIV
       
   397 ><DIV
       
   398 CLASS="EXAMPLE"
       
   399 ><A
       
   400 NAME="AEN351"
       
   401 ></A
       
   402 ><P
       
   403 ><B
       
   404 >Example 3-11. Interpreting Key Event Information</B
       
   405 ></P
       
   406 ><PRE
       
   407 CLASS="PROGRAMLISTING"
       
   408 >&#13;    #include "SDL.h"
       
   409 
       
   410     /* Function Prototypes */
       
   411     void PrintKeyInfo( SDL_KeyboardEvent *key );
       
   412     void PrintModifiers( SDLMod mod );
       
   413 
       
   414     /* main */
       
   415     int main( int argc, char *argv[] ){
       
   416         
       
   417         SDL_Event event;
       
   418         int quit = 0;
       
   419         
       
   420         /* Initialise SDL */
       
   421         if( SDL_Init( SDL_INIT_VIDEO ) &#60; 0){
       
   422             fprintf( stderr, "Could not initialise SDL: %s\n", SDL_GetError() );
       
   423             exit( -1 );
       
   424         }
       
   425 
       
   426         /* Set a video mode */
       
   427         if( !SDL_SetVideoMode( 320, 200, 0, 0 ) ){
       
   428             fprintf( stderr, "Could not set video mode: %s\n", SDL_GetError() );
       
   429             SDL_Quit();
       
   430             exit( -1 );
       
   431         }
       
   432 
       
   433         /* Enable Unicode translation */
       
   434         SDL_EnableUNICODE( 1 );
       
   435 
       
   436         /* Loop until an SDL_QUIT event is found */
       
   437         while( !quit ){
       
   438 
       
   439             /* Poll for events */
       
   440             while( SDL_PollEvent( &#38;event ) ){
       
   441                 
       
   442                 switch( event.type ){
       
   443                     /* Keyboard event */
       
   444                     /* Pass the event data onto PrintKeyInfo() */
       
   445                     case SDL_KEYDOWN:
       
   446                     case SDL_KEYUP:
       
   447                         PrintKeyInfo( &#38;event.key );
       
   448                         break;
       
   449 
       
   450                     /* SDL_QUIT event (window close) */
       
   451                     case SDL_QUIT:
       
   452                         quit = 1;
       
   453                         break;
       
   454 
       
   455                     default:
       
   456                         break;
       
   457                 }
       
   458 
       
   459             }
       
   460 
       
   461         }
       
   462 
       
   463         /* Clean up */
       
   464         SDL_Quit();
       
   465         exit( 0 );
       
   466     }
       
   467 
       
   468     /* Print all information about a key event */
       
   469     void PrintKeyInfo( SDL_KeyboardEvent *key ){
       
   470         /* Is it a release or a press? */
       
   471         if( key-&#62;type == SDL_KEYUP )
       
   472             printf( "Release:- " );
       
   473         else
       
   474             printf( "Press:- " );
       
   475 
       
   476         /* Print the hardware scancode first */
       
   477         printf( "Scancode: 0x%02X", key-&#62;keysym.scancode );
       
   478         /* Print the name of the key */
       
   479         printf( ", Name: %s", SDL_GetKeyName( key-&#62;keysym.sym ) );
       
   480         /* We want to print the unicode info, but we need to make */
       
   481         /* sure its a press event first (remember, release events */
       
   482         /* don't have unicode info                                */
       
   483         if( key-&#62;type == SDL_KEYDOWN ){
       
   484             /* If the Unicode value is less than 0x80 then the    */
       
   485             /* unicode value can be used to get a printable       */
       
   486             /* representation of the key, using (char)unicode.    */
       
   487             printf(", Unicode: " );
       
   488             if( key-&#62;keysym.unicode &#60; 0x80 &#38;&#38; key-&#62;keysym.unicode &#62; 0 ){
       
   489                 printf( "%c (0x%04X)", (char)key-&#62;keysym.unicode,
       
   490                         key-&#62;keysym.unicode );
       
   491             }
       
   492             else{
       
   493                 printf( "? (0x%04X)", key-&#62;keysym.unicode );
       
   494             }
       
   495         }
       
   496         printf( "\n" );
       
   497         /* Print modifier info */
       
   498         PrintModifiers( key-&#62;keysym.mod );
       
   499     }
       
   500 
       
   501     /* Print modifier info */
       
   502     void PrintModifiers( SDLMod mod ){
       
   503         printf( "Modifers: " );
       
   504 
       
   505         /* If there are none then say so and return */
       
   506         if( mod == KMOD_NONE ){
       
   507             printf( "None\n" );
       
   508             return;
       
   509         }
       
   510 
       
   511         /* Check for the presence of each SDLMod value */
       
   512         /* This looks messy, but there really isn't    */
       
   513         /* a clearer way.                              */
       
   514         if( mod &#38; KMOD_NUM ) printf( "NUMLOCK " );
       
   515         if( mod &#38; KMOD_CAPS ) printf( "CAPSLOCK " );
       
   516         if( mod &#38; KMOD_LCTRL ) printf( "LCTRL " );
       
   517         if( mod &#38; KMOD_RCTRL ) printf( "RCTRL " );
       
   518         if( mod &#38; KMOD_RSHIFT ) printf( "RSHIFT " );
       
   519         if( mod &#38; KMOD_LSHIFT ) printf( "LSHIFT " );
       
   520         if( mod &#38; KMOD_RALT ) printf( "RALT " );
       
   521         if( mod &#38; KMOD_LALT ) printf( "LALT " );
       
   522         if( mod &#38; KMOD_CTRL ) printf( "CTRL " );
       
   523         if( mod &#38; KMOD_SHIFT ) printf( "SHIFT " );
       
   524         if( mod &#38; KMOD_ALT ) printf( "ALT " );
       
   525         printf( "\n" );
       
   526     }</PRE
       
   527 ></DIV
       
   528 ></DIV
       
   529 ><DIV
       
   530 CLASS="SECT2"
       
   531 ><H2
       
   532 CLASS="SECT2"
       
   533 ><A
       
   534 NAME="AEN354"
       
   535 ></A
       
   536 >Game-type Input</H2
       
   537 ><P
       
   538 >I have found that people using keyboard events for games and other interactive applications don't always understand one fundemental point.</P
       
   539 ><A
       
   540 NAME="AEN357"
       
   541 ></A
       
   542 ><BLOCKQUOTE
       
   543 CLASS="BLOCKQUOTE"
       
   544 ><P
       
   545 >Keyboard events <SPAN
       
   546 CLASS="emphasis"
       
   547 ><I
       
   548 CLASS="EMPHASIS"
       
   549 >only</I
       
   550 ></SPAN
       
   551 > take place when a keys state changes from being unpressed to pressed, and vice versa.</P
       
   552 ></BLOCKQUOTE
       
   553 ><P
       
   554 >Imagine you have an image of an alien that you wish to move around using the cursor keys: when you pressed the left arrow key you want him to slide over to the left, and when you press the down key you want him to slide down the screen. Examine the following code; it highlights an error that many people have made.
       
   555 <PRE
       
   556 CLASS="PROGRAMLISTING"
       
   557 >    /* Alien screen coordinates */
       
   558     int alien_x=0, alien_y=0;
       
   559     .
       
   560     .
       
   561     /* Initialise SDL and video modes and all that */
       
   562     .
       
   563     /* Main game loop */
       
   564     /* Check for events */
       
   565     while( SDL_PollEvent( &#38;event ) ){
       
   566         switch( event.type ){
       
   567             /* Look for a keypress */
       
   568             case SDL_KEYDOWN:
       
   569                 /* Check the SDLKey values and move change the coords */
       
   570                 switch( event.key.keysym.sym ){
       
   571                     case SDLK_LEFT:
       
   572                         alien_x -= 1;
       
   573                         break;
       
   574                     case SDLK_RIGHT:
       
   575                         alien_x += 1;
       
   576                         break;
       
   577                     case SDLK_UP:
       
   578                         alien_y -= 1;
       
   579                         break;
       
   580                     case SDLK_DOWN:
       
   581                         alien_y += 1;
       
   582                         break;
       
   583                     default:
       
   584                         break;
       
   585                 }
       
   586             }
       
   587         }
       
   588     }
       
   589     .
       
   590     .</PRE
       
   591 >
       
   592 At first glance you may think this is a perfectly reasonable piece of code for the task, but it isn't. Like I said keyboard events only occur when a key changes state, so the user would have to press and release the left cursor key 100 times to move the alien 100 pixels to the left.</P
       
   593 ><P
       
   594 >To get around this problem we must not use the events to change the position of the alien, we use the events to set flags which are then used in a seperate section of code to move the alien. Something like this:</P
       
   595 ><DIV
       
   596 CLASS="EXAMPLE"
       
   597 ><A
       
   598 NAME="AEN363"
       
   599 ></A
       
   600 ><P
       
   601 ><B
       
   602 >Example 3-12. Proper Game Movement</B
       
   603 ></P
       
   604 ><PRE
       
   605 CLASS="PROGRAMLISTING"
       
   606 >    /* Alien screen coordinates */
       
   607     int alien_x=0, alien_y=0;
       
   608     int alien_xvel=0, alien_yvel=0;
       
   609     .
       
   610     .
       
   611     /* Initialise SDL and video modes and all that */
       
   612     .
       
   613     /* Main game loop */
       
   614     /* Check for events */
       
   615     while( SDL_PollEvent( &#38;event ) ){
       
   616         switch( event.type ){
       
   617             /* Look for a keypress */
       
   618             case SDL_KEYDOWN:
       
   619                 /* Check the SDLKey values and move change the coords */
       
   620                 switch( event.key.keysym.sym ){
       
   621                     case SDLK_LEFT:
       
   622                         alien_xvel = -1;
       
   623                         break;
       
   624                     case SDLK_RIGHT:
       
   625                         alien_xvel =  1;
       
   626                         break;
       
   627                     case SDLK_UP:
       
   628                         alien_yvel = -1;
       
   629                         break;
       
   630                     case SDLK_DOWN:
       
   631                         alien_yvel =  1;
       
   632                         break;
       
   633                     default:
       
   634                         break;
       
   635                 }
       
   636                 break;
       
   637             /* We must also use the SDL_KEYUP events to zero the x */
       
   638             /* and y velocity variables. But we must also be       */
       
   639             /* careful not to zero the velocities when we shouldn't*/
       
   640             case SDL_KEYUP:
       
   641                 switch( event.key.keysym.sym ){
       
   642                     case SDLK_LEFT:
       
   643                         /* We check to make sure the alien is moving */
       
   644                         /* to the left. If it is then we zero the    */
       
   645                         /* velocity. If the alien is moving to the   */
       
   646                         /* right then the right key is still press   */
       
   647                         /* so we don't tocuh the velocity            */
       
   648                         if( alien_xvel &#60; 0 )
       
   649                             alien_xvel = 0;
       
   650                         break;
       
   651                     case SDLK_RIGHT:
       
   652                         if( alien_xvel &#62; 0 )
       
   653                             alien_xvel = 0;
       
   654                         break;
       
   655                     case SDLK_UP:
       
   656                         if( alien_yvel &#60; 0 )
       
   657                             alien_yvel = 0;
       
   658                         break;
       
   659                     case SDLK_DOWN:
       
   660                         if( alien_yvel &#62; 0 )
       
   661                             alien_yvel = 0;
       
   662                         break;
       
   663                     default:
       
   664                         break;
       
   665                 }
       
   666                 break;
       
   667             
       
   668             default:
       
   669                 break;
       
   670         }
       
   671     }
       
   672     .
       
   673     .
       
   674     /* Update the alien position */
       
   675     alien_x += alien_xvel;
       
   676     alien_y += alien_yvel;</PRE
       
   677 ></DIV
       
   678 ><P
       
   679 >As can be seen, we use two extra variables, alien_xvel and alien_yvel, which represent the motion of the ship, it is these variables that we update when we detect keypresses and releases.</P
       
   680 ></DIV
       
   681 ></DIV
       
   682 ><DIV
       
   683 CLASS="NAVFOOTER"
       
   684 ><HR
       
   685 ALIGN="LEFT"
       
   686 WIDTH="100%"><TABLE
       
   687 SUMMARY="Footer navigation table"
       
   688 WIDTH="100%"
       
   689 BORDER="0"
       
   690 CELLPADDING="0"
       
   691 CELLSPACING="0"
       
   692 ><TR
       
   693 ><TD
       
   694 WIDTH="33%"
       
   695 ALIGN="left"
       
   696 VALIGN="top"
       
   697 ><A
       
   698 HREF="guideinput.html"
       
   699 ACCESSKEY="P"
       
   700 >Prev</A
       
   701 ></TD
       
   702 ><TD
       
   703 WIDTH="34%"
       
   704 ALIGN="center"
       
   705 VALIGN="top"
       
   706 ><A
       
   707 HREF="index.html"
       
   708 ACCESSKEY="H"
       
   709 >Home</A
       
   710 ></TD
       
   711 ><TD
       
   712 WIDTH="33%"
       
   713 ALIGN="right"
       
   714 VALIGN="top"
       
   715 ><A
       
   716 HREF="guideexamples.html"
       
   717 ACCESSKEY="N"
       
   718 >Next</A
       
   719 ></TD
       
   720 ></TR
       
   721 ><TR
       
   722 ><TD
       
   723 WIDTH="33%"
       
   724 ALIGN="left"
       
   725 VALIGN="top"
       
   726 >Input handling</TD
       
   727 ><TD
       
   728 WIDTH="34%"
       
   729 ALIGN="center"
       
   730 VALIGN="top"
       
   731 ><A
       
   732 HREF="guideinput.html"
       
   733 ACCESSKEY="U"
       
   734 >Up</A
       
   735 ></TD
       
   736 ><TD
       
   737 WIDTH="33%"
       
   738 ALIGN="right"
       
   739 VALIGN="top"
       
   740 >Examples</TD
       
   741 ></TR
       
   742 ></TABLE
       
   743 ></DIV
       
   744 ></BODY
       
   745 ></HTML
       
   746 >