Silverlight Games 101

Write games in Silverlight 2 using C# by Bill Reiss
Our upcoming Silverlight book for beginners (includes a great chapter on game development in Silverlight!) Hello! Silverlight 2 with Dave Campbell, available online now!



Pages

    Recent posts

    Navigation

    Archive

    Blogroll

      Tampa Divorce Lawyer

      North of Tampa in Lutz, Florida. A Tampa Divorce Lawyer focusing on family, divorce, and real estate law.

      Disclaimer

      The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

      Keyboard Input

      Source code for this tutorial: http://silverlightrocks.com/Community/files/folders/slg101_tutorials/entry17.aspx

      Now that we can rotate the ship using the game loop, let's add a way to control this rotation using the keyboard. You main forms of human input in a Silverlight application will typically be the keyboard or the mouse, I'll write a tutorial on mouse input in the future, but the mouse buttons generally behave like the keyboard buttons, and are actually a bit simpler.

      Introducing SLG101Utilities

      As I progress through these tutorials, there will be classes and code that are not specific to this particular game, and to make it easier to take advantage of them in your own games, I have added a SLG101Utilities project to the main game project. Eventually I'll make this available separately but for now since it will change a lot, it will be packaged with the SpaceRocks solution.

      Keyboard Overview

      Since Silverlight is a cross platform framework, keyboard handling is a bit different than what you may be used to. The KeyDown and KeyUp events pass a KeyboardEventArgs object which contains a Key and a PlatformKey field. The Key field contains the common keys to both Windows and the Mac and the values for each key are listed here:

      http://msdn2.microsoft.com/en-us/library/bb232871.aspx

      Since you typically would want your browser-based game to work on as many platforms as possible without custom code, you'll probably stick to using the Key field and ignore the PlatformKey field.

      NOTE: The following will probably change before 1.1 goes to release.

      There currently isn't a Key enum defined in Silverlight 1.1 Alpha, so I have defined my own in SLG101Utilities, using the same values specified in the URL above. I have defined this key enum in Key.cs.

      Trapping Keyboard Events

      Keyboard handling in Silverlight 1.1 Alpha consists of handling the KeyDown and KeyUp events on the root canvas. This is the canvas that is associated with the Page class in SpaceRocks (since we didn't rename the PAge class after the Orcas new project wizard generated it for us). Adding event listeners to other Canvas objects will cause errors.

      To make things easier from a game development standpoint, it's typically easier to poll whether a key is pressed during the game loop than to handle the key events and set states appropriately. So in SLG101Utilities, I have added a KeyHandler class which makes this simple. Here is the source code for the KeyHandler class:

          public class KeyHandler
          {
              bool[] isPressed = new bool[255];
              Canvas targetCanvas = null;
              public void ClearKeyPresses()
              {
                  for (int i = 0; i < 255; i++)
                  {
                      isPressed[i] = false;
                  }
              }
      
              public void Attach(Canvas target)
              {
                  ClearKeyPresses();
                  targetCanvas = target;
                  target.KeyDown += new KeyboardEventHandler(target_KeyDown);
                  target.KeyUp += new KeyboardEventHandler(target_KeyUp);
                  target.LostFocus += new EventHandler(target_LostFocus);
              }
      
              public void Detach(Canvas target)
              {
                  target.KeyDown -= new KeyboardEventHandler(target_KeyDown);
                  target.KeyUp -= new KeyboardEventHandler(target_KeyUp);
                  target.LostFocus -= new EventHandler(target_LostFocus);
                  ClearKeyPresses();
              }
      
              void target_KeyDown(object sender, KeyboardEventArgs e)
              {
                  isPressed[e.Key] = true;
              }
      
              void target_KeyUp(object sender, KeyboardEventArgs e)
              {
                  isPressed[e.Key] = false;
              }
                  
              void target_LostFocus(object sender, EventArgs e)
              {
                  ClearKeyPresses();            
              }
      
      
              public bool IsKeyPressed(Key k)
              {
                  int v = (int)k;
                  if (v < 0 || v > 82) return false;
                  return isPressed[v];
              }
      
          }
      

      Basically how it works is that you call the Attach() method of the KeyHandler object passing in your root canvas object. This Attach method wires up the events for your root canvas so that they are handled by the KeyHandler object. Then in your game loop, you would call the IsKeyPressed() method for each key that you care about. The LostFocus event is important since if a key is being pressed when you lose focus, you won't see the KeyUp event and the key will get "stuck" in the down position. So on LostFocus, KeyHandler clears all of the currently pressed keys.

      So now to use this in the SpaceRocks game.

      The namespace for the SLG101Utilities library is SilverlightGames101.Utilities. So first at the top of the Page.xaml.cs file, let's add a using statement for easier access to the KeyHandler class:

      using SilverlightGames101.Utilities;
      Now declare a KeyHandler field in the Page class
      KeyHandler keyHandler = new KeyHandler();

      In Page_Loaded, we need to Attach to the keyHandler, like this:

      keyHandler.Attach(this);

      and now all that's left is to check which keys are pressed in the game loop. For this game, we'll use the standard left, right, up keys that a lot of games use, where W=Thrust, A=Left, D=Right, and Space=Fire. For now, we'll just handle the Left and Right keys. So remove the test code from the last tutorial from the gameLoop_Completed method (the ship.RotationAngle++ statement) and replace it with the following:

      if (keyHandler.IsKeyPressed(Key.A))
      {
          ship.RotationAngle -= rotationSpeed;
      }
      if (keyHandler.IsKeyPressed(Key.D))
      {
          ship.RotationAngle += rotationSpeed;
      }
      

      If the A key is pressed, we'll subtract rotationSpeed from the rotation angle, and if D is pressed, we'll add the rotationSpeed. Define rotationSpeed as a field in the Page class, as follows:

      float rotationSpeed = 3;

      You can adjust this value to change the speed of rotation, but it seems to be about right.

      We're done for now, you should now be able to control the rotation of the ship using the A and D keys.

      Posted: May 20 2007, 06:21 by Bill Reiss | Comments (8) RSS comment feed |
      • Currently 0/5 Stars.
      • 1
      • 2
      • 3
      • 4
      • 5
      Filed under: Games

      Comments

      Comments are closed