XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   2D Series finished!
My Book: Out Now!
      
       Go to section on this site

Additional info


Latest Forum posts

 error x3000:syntax error
  Posted by: Anonymous
  When: 02/09/2010 at 06:55:17

 Reflection problem in corners ...
  Posted by: Anonymous
  When: 31/08/2010 at 20:53:30

 OcTree Question
  Posted by: radulph
  When: 31/08/2010 at 18:00:04

 model problems
  Posted by: Archenon
  When: 30/08/2010 at 05:54:27

 Changing computer breaks my game
  Posted by: Archenon
  When: 30/08/2010 at 05:49:50

 model problems
  Posted by: muffinman
  When: 28/08/2010 at 16:58:10

 Vertices problem
  Posted by: Anonymous
  When: 27/08/2010 at 15:35:36

 Changing computer breaks my game
  Posted by: radulph
  When: 27/08/2010 at 07:12:24

 effects file and XNA 4.0 (Beta)
  Posted by: radulph
  When: 26/08/2010 at 06:33:33

 Changing computer breaks my game
  Posted by: radulph
  When: 26/08/2010 at 06:27:59


Ads

Reading out the Keyboard

In this chapter, we’ll see how easy it is in XNA to read the keyboard input. As an example, whenever the user presses the left or right button, the angle of the cannon of the current player will be adjusted. Let’s start by adding this variable at the top of our code, so we know which cannon to adjust:

 int currentPlayer = 0;

Reading out the keyboard should be done quite frequently, as it is used to update our game logic such as the angles of the cannon. Therefore, we should do this in the Update method. To keep our Update method clean, we will code a method ProcessKeyboard which we will call from the Update method.

 private void ProcessKeyboard()
 {
     KeyboardState keybState = Keyboard.GetState();
     if (keybState.IsKeyDown(Keys.Left))
         players[currentPlayer].Angle -= 0.01f;
     if (keybState.IsKeyDown(Keys.Right))
         players[currentPlayer].Angle += 0.01f;
 }

This code is basically all we need! The first line retrieves the current state of the keyboard, holding which keys are current pressed. We use this KeyboardState object to the whether the Left and Right arrow keys are currently down, and if this is the case we change the angle of the current player.

Now let’s not forget to call this method from our Update method, ensuring the keyboard is read out exactly 60 times each second:

 ProcessKeyboard();

Now run this code! When you press the left and right arrow keys, the cannon of the first (red) player will rotate. However, at this moment you are able to rotate the cannon so it’s colliding with the terrain, so we should add this little logic to the end of the ProcessKeyboard method:

 if (players[currentPlayer].Angle > MathHelper.PiOver2)
     players[currentPlayer].Angle = -MathHelper.PiOver2;
 if (players[currentPlayer].Angle < -MathHelper.PiOver2)
     players[currentPlayer].Angle = MathHelper.PiOver2;

In this code, you need to remember that Pi (=3.14) radians correspond to 180 degrees, so PiOver2 radians correspond to 90 degrees. Then it’s easy: if the cannon is at 90 degrees (meaning horizontally to the right), and the right button is pressed, the angle changes to -90 degrees to it is pointing to the left. The last 2 lines make this true for the other way around. Try what this gives when running the code!

Now we will add a last block of code to our ProcessKeyboard method, which allows the player to adjust the Power of the cannon:

 if (keybState.IsKeyDown(Keys.Down))
     players[currentPlayer].Power -= 1;
 if (keybState.IsKeyDown(Keys.Up))
     players[currentPlayer].Power += 1;
 if (keybState.IsKeyDown(Keys.PageDown))
     players[currentPlayer].Power -= 20;
 if (keybState.IsKeyDown(Keys.PageUp))
     players[currentPlayer].Power += 20;
 
 if (players[currentPlayer].Power > 1000)
     players[currentPlayer].Power = 1000;
 if (players[currentPlayer].Power < 0)
     players[currentPlayer].Power = 0;

When the Up or Down arrows are pressed, the power is incremented or decremented by one. Since this way it can take a while to reach a high power, if the PageUp or PageDown keys are pressed the incrementation and decrementation will be done at much larger steps. The last 4 lines simply limit the Power value between 0 and 1000.




DirectX Tutorial 6 - Keyboard input

If you appreciate the amount of time I spend creating and updating
these pages, feel free to donate -- any amount is welcome !



Click here to go to the forum on this chapter!

Or click on one of the topics on this chapter to go there:
  • Suggestion to change a few lines
          In the tutorial, these four lines: if (...
  • Confused about Cannon Rotation
          I haven't coded in about a hundred years, so bear...
  • Mistake in tutorial code
          I've noticed some mistakes in the code handling t...



    That’s it for this chapter! You can see the cannon rotate on your keyboard input, but it’s hard to see the Power is changing. Therefore, next chapter we will see how to render text to the screen, so we can print the Angle and Power of the current player to the screen!

    The code thus far:

     using System;
     using System.Collections.Generic;
     using Microsoft.Xna.Framework;
     using Microsoft.Xna.Framework.Audio;
     using Microsoft.Xna.Framework.Content;
     using Microsoft.Xna.Framework.GamerServices;
     using Microsoft.Xna.Framework.Graphics;
     using Microsoft.Xna.Framework.Input;
     using Microsoft.Xna.Framework.Net;
     using Microsoft.Xna.Framework.Storage;
     
     namespace XNAtutorial
     {
         public struct PlayerData
         {
             public Vector2 Position;
             public bool IsAlive;
             public Color Color;
             public float Angle;
             public float Power;
         }
     
         public class Game1 : Microsoft.Xna.Framework.Game
         {
             GraphicsDeviceManager graphics;
             SpriteBatch spriteBatch;
             GraphicsDevice device;
     
             int screenWidth;
             int screenHeight;
     
             Texture2D backgroundTexture;
             Texture2D foregroundTexture;
             Texture2D carriageTexture;
             Texture2D cannonTexture;
     
             PlayerData[] players;
             int numberOfPlayers = 4;
             float playerScaling;
             int currentPlayer = 0;
     
             public Game1()
             {
                 graphics = new GraphicsDeviceManager(this);
                 Content.RootDirectory = "Content";
             }
     
             protected override void Initialize()
             {
                 graphics.PreferredBackBufferWidth = 500;
                 graphics.PreferredBackBufferHeight = 500;
                 graphics.IsFullScreen = false;
                 graphics.ApplyChanges();
                 Window.Title = "Riemer's 2D XNA Tutorial";
     
                 base.Initialize();
             }
     
             protected override void LoadContent()
             {
                 device = graphics.GraphicsDevice;
                 spriteBatch = new SpriteBatch(device);
     
                 screenWidth = device.PresentationParameters.BackBufferWidth;
                 screenHeight = device.PresentationParameters.BackBufferHeight;
     

                backgroundTexture = Content.Load<Texture2D> ("background");
                foregroundTexture = Content.Load<Texture2D> ("foreground");
                carriageTexture = Content.Load<Texture2D> ("carriage");
                cannonTexture = Content.Load<Texture2D> ("cannon");
                SetUpPlayers();
                playerScaling = 40.0f / (float)carriageTexture.Width;
            }

            private void SetUpPlayers()
            {
                Color[] playerColors = new Color[10];
                playerColors[0] = Color.Red;
                playerColors[1] = Color.Green;
                playerColors[2] = Color.Blue;
                playerColors[3] = Color.Purple;
                playerColors[4] = Color.Orange;
                playerColors[5] = Color.Indigo;
                playerColors[6] = Color.Yellow;
                playerColors[7] = Color.SaddleBrown;
                playerColors[8] = Color.Tomato;
                playerColors[9] = Color.Turquoise;

                players = new PlayerData[numberOfPlayers];
                for (int i = 0; i < numberOfPlayers; i++)
                {
                    players[i].IsAlive = true;
                    players[i].Color = playerColors[i];
                    players[i].Angle = MathHelper.ToRadians(90);
                    players[i].Power = 100;                
                }

                players[0].Position = new Vector2(100, 193);
                players[1].Position = new Vector2(200, 212);
                players[2].Position = new Vector2(300, 361);
                players[3].Position = new Vector2(400, 164);
            }

            protected override void UnloadContent()
            {
            }

            protected override void Update(GameTime gameTime)
            {
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();


                 ProcessKeyboard();
     
                 base.Update(gameTime);
             }
     
             private void ProcessKeyboard()
             {
                 KeyboardState keybState = Keyboard.GetState();
                 if (keybState.IsKeyDown(Keys.Left))
                     players[currentPlayer].Angle -= 0.01f;
                 if (keybState.IsKeyDown(Keys.Right))
                     players[currentPlayer].Angle += 0.01f;
     
                 if (players[currentPlayer].Angle > MathHelper.PiOver2)
                     players[currentPlayer].Angle = -MathHelper.PiOver2;
                 if (players[currentPlayer].Angle < -MathHelper.PiOver2)
                     players[currentPlayer].Angle = MathHelper.PiOver2;
     
                 if (keybState.IsKeyDown(Keys.Down))
                     players[currentPlayer].Power -= 1;
                 if (keybState.IsKeyDown(Keys.Up))
                     players[currentPlayer].Power += 1;
                 if (keybState.IsKeyDown(Keys.PageDown))
                     players[currentPlayer].Power -= 20;
                 if (keybState.IsKeyDown(Keys.PageUp))
                     players[currentPlayer].Power += 20;
     
                 if (players[currentPlayer].Power > 1000)
                     players[currentPlayer].Power = 1000;
                 if (players[currentPlayer].Power < 0)
                     players[currentPlayer].Power = 0;
             }
     
             protected override void Draw(GameTime gameTime)
             {
                 graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
     
                 spriteBatch.Begin();
                 DrawScenery();
                 DrawPlayers();
                 spriteBatch.End();
     
                 base.Draw(gameTime);
             }
     
             private void DrawScenery()
             {
                 Rectangle screenRectangle = new Rectangle(0, 0, screenWidth, screenHeight);
                 spriteBatch.Draw(backgroundTexture, screenRectangle, Color.White);
                 spriteBatch.Draw(foregroundTexture, screenRectangle, Color.White);
             }
     
             private void DrawPlayers()
             {
                 foreach (PlayerData player in players)
                 {
                     if (player.IsAlive)
                     {
                         int xPos = (int)player.Position.X;
                         int yPos = (int)player.Position.Y;
                         Vector2 cannonOrigin = new Vector2(11, 50);
     
                         spriteBatch.Draw(cannonTexture, new Vector2(xPos + 20, yPos - 10), null, player.Color, player.Angle, cannonOrigin, playerScaling, SpriteEffects.None, 1);
                         spriteBatch.Draw(carriageTexture, player.Position, null, player.Color, 0, new Vector2(0, carriageTexture.Height), playerScaling, SpriteEffects.None, 0);
                     }
                 }
             }
         }
     }
     


    Google
     
    Webwww.riemers.net


    If you appreciate the amount of time I spend creating and updating
    these pages, feel free to donate -- any amount is welcome !



    - Website design & XNA + DirectX code : Riemer Grootjans -
    ©2003 - 2008 Riemer Grootjans
  • Translations

    This site in English
    This site in Korean
    This site in Czech

    Microsoft MVP Award



    2007 - 2009 MVP Award
    DirectX - XNA

    Contents

    News
    Home
    Forum
    XNA 2.0 Recipes Book (8)
    XNA 3.0 Recipes Book (8)
    Downloads
    Extra Reading (3)
    Matrices: geometrical
    Matrix Mathematics
    Homogenous matrices
    Community Projects (1)
    Tutorials (160)
    XNA 3.0 using C# (89)
    2D Series: Shooters! (22)
    Starting a project
    Drawing fullscreen images
    Positioning images
    SpriteBatch.Draw()
    Rotation
    Keyboard input
    Writing text
    Angle to Direction
    Direction to Angle
    Smoke trail
    Manual texture creation
    Random terrain
    Texture to Colors
    Coll Detection Overview
    Coll Detection Matrices
    Putting CD into practice
    Particles
    Additive alpha blending
    Particle engine
    Adding craters
    Sound in XNA
    Resolution independency
    3D Series 1: Terrain (13)
    3D Series 2: Flightsim (14)
    3D Series 3: HLSL (18)
    3D Series 4: Adv. terrain (19)
    Short Tuts (3)
    DirectX using C# (54)
    DirectX using C++ (15)
    DirectX using VB (2)
    -- Expand all --


    Thank you!

    Support this site --
    any amount is welcome !

    Stay up-to-date

    I don't have the time to keep a News section, so stay informed about the updates by clicking on this RSS file!