HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Registering multiple keypresses simultaneously, very slow

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
registeringkeypressesslowsimultaneouslymultiplevery

Problem

I'm working on a Pong game and right now I'm working on being able to register multiple KeyDown presses simulatenously. I used the Win32 native method GetKeyBoardState first to loop through all of the virtual keys and see if any of the keys matched the game input keys. Now this worked just fine but in the interest of optimization I figured that it would be quicker to use GetKeyState since there are only 4 valid input keys and then simply check if any of those keys are pressed down.

Surprisingly it is incredibly slow and choppy, a lot worse than GetKeyBoardState so I'm wondering if there's something in my code that's slowing it down. Here's the complete implementation

NativeMethods.cs

internal static class NativeMethods
    {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetKeyboardState(byte[] lpKeyState);

        [DllImport("user32.dll")]
        internal static extern short GetKeyState(int nVirtKey);
    }


Keyboard.cs

static class Keyboard
{
    public static bool GetKeyState(Keys vKey)
    {
        short results = NativeMethods.GetKeyState((int)vKey);
        // We're only going to use this to look for arrow keys so
        // No need to differntiate results based on low or high order bits
        switch (results) 
        {
            case 0: //KEY STATE: NOT PRESSED
                return false;
            case -127: //KEY STATE: PRESSED
                return true;
        }
        return false;
    }


GameForm.cs

```
private void GameForm_KeyDown(object sender, KeyEventArgs e)
{
var movementData = new Tuple(-1, Pong.Move.Down);

//Check how many keys that are pressed down (for example both players might be moving their paddles simulatenously)
var pressedKeys = inputKeys.Where(key => Keyboard.GetKeyState(key));

//Check if pressed key equals any of the player assigned keys.. If so call MovePaddle()

Solution

What is impacting you performance so heavily is the creation of Tuples everytime you recieve a keypressed event.

creating objects is slow. What you should do instead is, directly apply the changes to the moving objects (your two pong-thingies).

private void GameForm_KeyDown(object sender, KeyEventArgs e)
{
   var pressedKeys = inputKeys.Where(key => Keyboard.GetKeyState(key));
   foreach(Keys key in pressedKeys)
      switch(key){
         case Keys.Up:
             leftPong.Positon += FIXEDVALUE;
             break;
         case Keys.Down:
             leftPong.Position -= FIXEDVALUE;
             break;
         //continue...

Code Snippets

private void GameForm_KeyDown(object sender, KeyEventArgs e)
{
   var pressedKeys = inputKeys.Where(key => Keyboard.GetKeyState(key));
   foreach(Keys key in pressedKeys)
      switch(key){
         case Keys.Up:
             leftPong.Positon += FIXEDVALUE;
             break;
         case Keys.Down:
             leftPong.Position -= FIXEDVALUE;
             break;
         //continue...

Context

StackExchange Code Review Q#47556, answer score: 2

Revisions (0)

No revisions yet.