High-Speed Input


As you played the Ping game introduced in earlier chapters, you may have noticed that the keyboard input was somewhat slow. In fact, it was possible for one player to keep the other player from moving her paddle by simply holding down a key and not releasing it. Problems like these are caused by the way in which Windows gets input from the keyboard. On its own, Windows is not made for high-speed input.

Before I launch into a fascinating (I hope) discussion of how do to high-speed input, it's probably best to define exactly what I mean by the term "high-speed input." In games, high-speed input is generally defined as the ability to get the state of an input device during each frame of animation. In other words, your game can do high-speed input if it can look at the keyboard during each animation frame and see which keys are pressed. That's not how Windows works. Instead, Windows sends your program messages that the program can respond to. When you're using LlamaWorks2D, you use a message map to call functions that respond to messages.

Factoid

High-speed input is also called real-time input.


Windows messages do not arrive at the program immediately after the player presses a key on the keyboard. They can take a while to get there. When you're doing something slow like typing in your name, it doesn't matter. The program will still be fast enough to get all of the letters you type and display them on the screen. LlamaWorks2D provides message maps so that you can handle slow tasks easily.

Using messages and message maps is all well and good when the player is doing something slow. However, it's not fast enough when he's trying to shoot a SnarfBeast that's running at his character with all four of its jaws open wide. In that situation, waiting for Windows messages to arrive at your message map will result in the SnarfBeast getting a nice meal with the player's character as the main course.

LlamaWorks2D provides a technique that enables you to get around having to use Windows messages. That technique is called immediate mode input.

Introducing Immediate Mode Input

Immediate mode input is something that I invented for LlamaWorks2D. Other game engines use similar techniques for getting high-speed input. In LlamaWorks2D, immediate mode input means that a program can examine the keyboard during each frame and determine immediately which keys are pressed.

Recall that LlamaWorks2D creates an application object that represents the program itself. The application object provides services that have to do with input, output, and the overall state of the program.

The LlamaWorks2D application class, which is called lw2d_app, contains a member function called IsKeyPressed(). The IsKeyPressed() function immediately checks the keyboard to determine whether the specified key is currently pressed down. If it is, IsKeyPressed() returns true. If it isn't, IsKeyPressed() returns false. You specify which key you're interested in by passing the key code to the IsKeyPressed() function. The key codes are defined in a list in the file LW2DInputDevice.h. The constants in the list all start with the letters KC, which stands for key code.

So, for instance, if you want to determine whether the right Shift key is pressed, you pass the value KC_RIGHT_SHIFT as the parameter to IsKeyPressed(). Or if you just want to know if any Shift key is pressed (right or left), you can pass the value KC_SHIFT. Likewise, if your game uses the spacebar to fire a weapon (lots of games do), you can pass the value KC_SPACEBAR to IsKeyPressed().

That's all there is to high-speed input when you're using LlamaWorks2D. You just call one function to determine whether any particular key on the keyboard is pressed. So now, let's see immediate mode input in action by revising the Ping program to use it.

Ping and Immediate Mode Input

Making a program use immediate mode input is very straightforward. All you need to do is call the IsKeyPressed() function from your UpdateFrame() function, or from a function that is called from UpdateFrame(). To add immediate mode input to Ping, I'll create a function in the ping class called GetKeyboardInput(). The GetKeyboardInput() function is called from the ping class's UpdateFrame() function. GetKeyboardInput() checks to see if particular keys are pressed. If they are, it responds by updating the movement of the paddle. If they aren't, it just returns to UpdateFrame(). Listing 13.4 gives the code for GetKeyboardInput() and the new version of the UpdateFrame() function.

Listing 13.4. Modifications to make Ping do immediate mode input

 1     bool ping::UpdateFrame() 2     { 3         bool updateOK = true; 4 5         if (!GameOver()) 6         { 7             GetKeyboardInput(); 8             // The rest of this function is unchanged from 9             // Chapter 8. It has been omitted to save space. 10        } 11 12            return (updateOK); 13        } 14 15 16 17        bool ping::OnKeyDown( 18            keyboard_input_message &theMessage) 19        { 20            switch (theMessage.keyCode) 21            { 22                case KC_ESCAPE: 23                case KC_Q: 24                    GameOver(true); 25                break; 26            } 27            return (false); 28        } 29 30 31        void ping::GetKeyboardInput() 32        { 33            vector paddleDirection; 34 35            if (theApp.IsKeyPressed(KC_UP_ARROW)) 36            { 37                paddleDirection.Y(15); 38                rightPaddle.Movement(paddleDirection); 39            } 40            else if (theApp.IsKeyPressed(KC_DOWN_ARROW)) 41            { 42                paddleDirection.Y(15); 43                rightPaddle.Movement(paddleDirection); 44            } 45 46            if (theApp.IsKeyPressed(KC_A)) 47            { 48                paddleDirection.Y(15); 49                leftPaddle.Movement(paddleDirection); 50            } 51            else if (theApp.IsKeyPressed(KC_Z)) 52            { 53            paddleDirection.Y(15); 54            leftPaddle.Movement(paddleDirection); 55        } 56    } 

As you examine Listing 13.4, you'll notice that most of the UpdateFrame() function is not there. I left it out to save space. You can see it by looking on the CD in the file Ping.cpp in the folder Source\Chapter13\Prog_13_02. The stuff that I left out is everything that hasn't changed since chapter 8. The only thing that's really new in the UpdateFrame() function is the call to GetKeyboardInput(), which appears on line 7 of Listing 13.4.

The code for the GetKeyboardInput() function starts on line 31. After declaring a variable on line 33, it calls the IsKeyPressed() function on line 35. Notice that the call to the IsKeyPressed() function is inside the parentheses of an if statement. The if statement tests the return value of the IsKeyPressed() function. If IsKeyPressed() returns TRue, it means the up arrow key is pressed. Therefore, the GetKeyboardInput() function executes the statements on lines 3738. If the up arrow is not being pressed, the IsKeyPressed() function returns false. In that case, GetKeyboardInput() calls IsKeyPressed() again on line 40 to see if the down arrow is currently pressed. If so, it executes the statements on lines 4243.

Tip

Use immediate mode input for player input that requires a fast response, such as fighting, shooting, dodging danger, or bravely running away. Use the LlamaWorks2D ON_WMKEYDOWN() macro in a message map to respond to program commands such as quit or save game. Use the ON_WMCHAR() macro in a message map when the player is typing in a string.


The GetKeyboardInput() function follows essentially the same pattern for the A and Z keys. It calls IsKeyPressed() on line 46 to see if the A key is pressed and executes the statements on lines 4849 if it is. If not, it tests to see if the player is pressing the Z key. If Z is pressed, GetKeyboardInput() executes the statements on lines 5354.

A final thing to note about Listing 13.4 is that it also contains the code for the ping class's OnKeyDown() function. You may recall from previous chapters that this function responds to the WM_KEYDOWN message that Windows sends to programs. The WM_KEYDOWN message comes to LlamaWorks2D programs through their message maps. Using immediate mode input in your game does not prevent you from also using message maps. The OnKeyDown() function in Listing 13.4 tells the game that it's done when the player presses the Escape or Q keys. Because this type of input does not require an immediate response, it is just the right kind of input for message maps.



Creating Games in C++(c) A Step-by-Step Guide
Creating Games in C++: A Step-by-Step Guide
ISBN: 0735714347
EAN: 2147483647
Year: N/A
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net