Keyboard events

One way to handle keyboard events is to set the form's KeyPreview property to true. Then the program can catch the form's KeyDown, KeyUp, and KeyPress events.

Unfortunately, those events have odd behaviors. If you press a key, the program receives a KeyDown event as you would expect. If you hold the key down, there is a small delay and then the program starts quickly receiving many KeyDown events. Generating many events by holding a key down isn't a problem. After all, you might want the ship to continue to accelerate as long as the up arrow is pressed. The trouble is that the events are not evenly spaced in time.

For example, suppose you press the up arrow key to accelerate the ship. The first KeyDown event occurs quickly, so the ship experiences a small acceleration. Next, there is a pause and then the ship receives many accelerations in rapid succession.

To avoid this problem, the example solution takes a different approach to handling keyboard events. Each time the move timer ticks, the Tick event handler calls the following ProcessKeys method to see if the user is currently pressing a key:

// Take action of the user has pressed an action key.
private void ProcessKeys()
{
// Do nothing if the ship has been destroyed.
if (TheShip.IsDestroyed) return;

// Require at least 250ms between shots.
const int msPerShot= 250;

// Shoot.
if (Keyboard.IsKeyDown(Key.Space))
{
// Make sure the required time has elapsed since the last shot.
TimeSpan timePassed = DateTime.Now - LastShot;
if (timePassed.TotalMilliseconds >= msPerShot)
{
Shoot();
}
}

// Accelerate.
if (Keyboard.IsKeyDown(Key.Up))
{
TheShip.Accelerate();
}

// Turn left.
if (Keyboard.IsKeyDown(Key.Left))
{
TheShip.TurnLeft();
}

// Turn right.
if (Keyboard.IsKeyDown(Key.Right))
{
TheShip.TurnRight();
}
}

If the ship has been destroyed, the method returns without doing anything. That prevents the user from being able to control the explosion after the ship has been destroyed.

If the ship has not been destroyed, the method uses the System.Windows.Input.Keyboard class's IsKeyDown method to see if the spacebar is pressed. If the spacebar is pressed, the code checks that at least 250 milliseconds have passed since the last time the user fired a bullet. If the program doesn't make that check, the user can fire an endless stream of bullets making the game a lot less challenging. If at least 250 milliseconds have passed since the previous shot, the code calls the Shoot method to play a sound and calls the ship object's MakeBullet method. The Shoot method is straightforward so I won't show it here.

You must add references to the PresentationCore and WindowsBase libraries in order to use the Keyboard class and the Key enumeration in a Windows Form application. Also note that the Keyboard class's IsKeyDown method only works in .NET Framework versions 4.0 and later, so be sure your application targets one of the more recent versions.

After it finishes looking for the spacebar, the program similarly looks for the up, left, and right arrow keys. If any of those keys is pressed, the code calls an appropriate ship method to make the ship accelerate or turn.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset