Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to handle and use event of simultaneously pressed two or more keys in C# - WASD keyboard game controls -

0.00/5 (No votes)
23 Oct 2016 1  
Example of handling multiple key press event

Introduction

Recently I have bumped to a simple but for me as C# beginner unsolvable problem.
How to use WASD keyboard keys in a manner as in any other computer game ?
 
Solution for such problem involves handling keyboard event of simultaneously pressed two or more keys.
 
In my program I have used two standard keyboard Key event handlers.
OnKeyDown and OnKeyUp for determining what keys are pressed and released,
but the program did not worked correctly.
 
When I press key A and while holding it down I press key W,
program works perfectly but when I release key W
the OnKeyDown event handler do not recognize that key A is still pressed.
 
After a lot of search for knowledge about such problem throughout the Internet,
I have found this answer :
 
Quote:
You are depending on the keyboard repeating a key when held down.
That stops working as soon as you press another key.
You instead need to use a Timer and in the Tick event handler
check which way you want to move. Now key-repeat no longer matters.
Set the timer's Interval property to 15 or 31 to get good consistency.
                                                       – Hans Passant
 
And finally here is an example of program that solves problem good enough
to be publicly shared as an TIP & Trick on Code Project.

Program overview

Program is developed as windows form application in C# 4.0 .Net 2.0.
After program start, by pressing WASD keys on the keyboard,
user can observe trough key flag counter value shown on screen,
how many times program has checked and confirmed the key down state of WASD keys.

 

downloadDownload open source code - 39.6 KB

 

Tip & Trick

Since that the standard OnKeyDown and OnKeyUp event handlers
can register when user press and release only one key and
not simultaneously pressed and released two or more keys,
the exception is key combination with Alt, Shift and Control key,
in this program those event handlers with key down flag variables
for each observed key, are used for determining and memorizing key down/up state.
 
For raising an action upon key down/up flag state program uses System.Windows.Forms.Timer class object that raises event at user defined time interval. It serves inside program as infinite loop with constant time
interval set in milliseconds, for raising Timer.Tick event handler trough which program calls user Main_Function(), where are defined actions that program is going to make upon user press/release keyboard key.
 

Using the code

Program code attached with this tip is designed for learning.
It is well commented and comments cover every aspect of problem solving.
Read it carefully and thoroughly.
 
For practical use, it is recommended to download the full solution created in IDE Sharp Develop. Open project in the same IDE or in the Visual Studio, build it and run program.
 

DownloadDownload open source code - 39.6 KB

 
C#
using System;
using System.Windows.Forms;

namespace WASD_keyboard_game_control
{
    public partial class MainForm : Form
    {

        //
        // Global variables declaration
        //

        //
        // Timer
        //
        // Implements a timer that
        // raises event at user defined interval
        //
        Timer Clock;

        //
        // Set Timer tick Interval in milliseconds
        //
        // By changing value of Interval,
        // we control how often the timer tick event handler is raised
        // and eventually the call frequency of Main_Function()
        //
        const int Interval = 15;

        //
        // Variables for counting the number
        // of times that program has confirmed
        // the key down state of WASD keys
        //
        int W = 0;
        int A = 0;
        int S = 0;
        int D = 0;

        //
        // Variables ( flags ) for memorizing
        // the key down state of WASD keys
        //
        // true  - key is down ( pressed )
        //
        // false - key is up ( released )
        //
        //
        bool w = false;
        bool a = false;
        bool s = false;
        bool d = false;

        //
        //
        //

        public MainForm()
        {
            //
            // The InitializeComponent() call is required
            // for Windows Forms designer support.
            //
            InitializeComponent();

            //
            // Call Initialize_Timer() function
            //
            Initialize_Timer();
        }
       

        void Initialize_Timer()
        {
            // Create new timer
            Clock = new Timer();

            // Set timer tick interval in milliseconds
            //
            // By changing value of interval,
            // we control how often the timer tick event handler is raised
            // and eventually the call frequency of Main_Function()
            //
            Clock.Interval = Interval;

            //
            // Add timer tick event handler
            //
            // This event handler is raised
            // every time timer make tick
            //
            // The smaller value for timer interval,
            // more often the event handler is raised
            //
            Clock.Tick += new System.EventHandler(this.ClockTick);

            //
            // Start timer
            //
            Clock.Start();
        }
       

        void ClockTick(object sender, EventArgs e)
        {
            //
            // Timer tick event handler
            //

            //
            // Call Main_Function()
            //
            Main_Function();

            //
            //
            //
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            //
            // This event handler is raised every time
            // some key on the keyboard is first pressed
            //

            base.OnKeyDown(e);

            //
            // Set corresponding key down flag state to true
            //

            if(e.KeyCode == Keys.W)
                w = true;
            if(e.KeyCode == Keys.A)
                a = true;
            if(e.KeyCode == Keys.S)
                s = true;
            if(e.KeyCode == Keys.D)
                d = true;
        }
       

        protected override void OnKeyUp(KeyEventArgs e)
        {
            //
            // This event handler is raised every time
            // some key on the keyboard is released
            //

            base.OnKeyUp(e);

            //
            // Set corresponding key down flag state to false
            //

            if(e.KeyCode == Keys.W)
                w = false;
            if(e.KeyCode == Keys.A)
                a = false;
            if(e.KeyCode == Keys.S)
                s = false;
            if(e.KeyCode == Keys.D)
                d = false;
        }
       

        void Main_Function()
        {
            //
            // Main function
            //

            //
            // This function is called every time the
            // timer tick event handler is raised
            //

            //
            // This function determines which key is pressed
            // upon key down flag value and updates corresponding counter value
            //
            // Counter value shows how many times program has confirmed the
            // key down state and not how many times user has pressed the key
            //
           

            //
            // Increase counter value if key is down
            //

            if(w)
                W++;
            if(a)
                A++;
            if(s)
                S++;          
            if(d)
                D++;

            //
            // Show values of counters
            //

            Label_W.Text = "W = " + W.ToString();
            Label_A.Text = "A = " + A.ToString();
            Label_S.Text = "S = " + S.ToString();
            Label_D.Text = "D = " + D.ToString();
        }
    }
}

Points of Interest

Learn how to handle simultaneously pressed two or more keyboard keys event and
simulate WASD game controls inside windows form application by using Timer class object.
 
After learning how to solve above problem,
I have learned that System.Windows.Forms.Timer class with its Timer.Tick event
is interesting and useful for many other similar applications.

History

Last updated 22.10.2016, Author

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here