1

I am trying to write a small space shooter game using C# and WPF. I want to be able to move my space ship up and down by keeping my up- or down key, respectively, pressed. That works. However, if I want to fire using the space button, the movement stops although I'd like it to continue. I am using a key event handler that is registered an implemented as follows:

MainWindow.KeyDown += new KeyEventHandler(OnKeyDown);

...

private void OnKeyDown(object sender, KeyEventArgs e)
{
    double Shift = 20;

    switch (e.Key)
    {
        case Key.Down:
            if (Y < Model.Height - Geometry.Height - Shift)
                Y += Shift;
            break;
        case Key.Up:
            if (Y > Shift)
                Y -= Shift;
            break;
        case Key.Space:
            Fire();
            break;
    }
}

Any ideas on how to acomplish what I want?

ToniBig
  • 836
  • 6
  • 21
  • Note that your basic concern is not unique to WPF and so Winforms-related questions contain lots of additional useful info. See e.g. https://stackoverflow.com/questions/10063580/winform-multiple-keys-pressed, https://stackoverflow.com/questions/709540/capture-multiple-key-downs-in-c-sharp, and https://stackoverflow.com/questions/29942437/removing-the-delay-after-keydown-event – Peter Duniho Mar 29 '20 at 01:05

2 Answers2

0

Have you tried adding the below line to the end of your method (iow. The last line in your method).

e.Handled = true;

I hope you have checked the question marked as duplicate.

You can also add the following on the first line of the method :

if (e.Handled) return;

Hope that sorts it out.

-1

Since you are writing a game, perhaps the best way out is to use the logic of game engine axes. Separate the movement logic from the action logic and use a timer to control the axis sensitivity:

using System.Timers;
...
//checks the key pressed every 50 milliseconds
Timer timer = new Timer(50); //tune this value to get the desired result
timer.Elapsed += Timer_Elapsed;
timer.Start();
...

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
    //timers execute on another Thread so this is necessary
    Dispatcher.Invoke(OnInputAxis);
}

private void OnInputAxis()
{
    if (Keyboard.IsKeyDown(Key.Down))
    {
        if (Y < Model.Height - Geometry.Height - Shift)
                Y += Shift;
    }

    if (Keyboard.IsKeyDown(Key.Up))
    {
         if (Y > Shift)
                Y -= Shift;
    }
}
...
//you can keep your fire action in a keydown event
private void OnKeyDown(object sender, KeyEventArgs e)
{
   if (e.Key == Key.Space)
   {
       fire();
   }
}


bandozia
  • 34
  • 2