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