简体   繁体   中英

keydown events cancelling other out c#

sorry again for asking a probable simple question but I have been searching among the internet for this solution but I am unable to. I am in Highschool programming working on a final project. I have everything done except this little part. I have 2 background workers made(One for each player) and I have keydown events turning these background workers on. Here is the code:

if (e.keycode == Keys.D)
{
    p1f = true;
    bgwPlayerOne.RunWorkerAsync();
}
if (e.keycode == Left)
{
    p2f = true;
    bgwPlayerTwo.RunWorkerAsync();
}

Okay, so I had to type that out because it is on my other computer which has no internet but that is the code in the keydown event. The variables tells that in the background worker which if statement to do. But, the main issue is that whenever I press D and Left Arrow Key at the same time, The one going before the other click is stopped and the most recent key event is started. I didn't have this issue when I was using timers previously(I was having a lag issue so I switched to multithread). If there are any questions about this please tell me, any help would be appreciated, thanks!

Updated*****

private void frmTankBattle_MapOne_KeyDown(object sender, KeyEventArgs e)
    {


            if (e.KeyCode == Keys.D)
            {
                p1f = true;
                bgwPlayerOne.RunWorkerAsync();

            }
            //System.Threading.Thread.Sleep(1);
            if (e.KeyCode == Keys.A)
            {
                p1b = true;
                bgwPlayerOne.RunWorkerAsync();
            }
            //System.Threading.Thread.Sleep(1);
            if (e.KeyCode == Keys.Left)
            {
                p2f = true;
                bgwPlayerTwo.RunWorkerAsync();
            }
            //System.Threading.Thread.Sleep(1);
            if (e.KeyCode == Keys.Right)
            {
                p2b = true;
                bgwPlayerTwo.RunWorkerAsync();
            }

            if (e.KeyCode == Keys.Space)
            {
                p1c = true;
                tmrPlayerOneCombat.Start();
            }


       // System.Threading.Thread.Sleep(1);
    }
private void frmTankBattle_MapOne_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.D)
        {
            p1f = false;
            p1b = false;
            bgwPlayerOne.CancelAsync();
        }
        if (e.KeyCode == Keys.A)
        {
            p1f = false;
            p1b = false;
            bgwPlayerOne.CancelAsync();
        }
        if (e.KeyCode == Keys.Left)
        {
            p2f = false;
            p2b = false;
            bgwPlayerTwo.CancelAsync();
        }
        if (e.KeyCode == Keys.Right)
        {
            p2f = false;
            p2b = false;
            bgwPlayerTwo.CancelAsync();
        }
    }

There are couple things wrong with your code and I will go thru them one by one.

Firstly KeyDown event will fire multiple times per second as long as any key has been hold down.

This means if RunWorkerAsync(); did not finish before the event fires for the second time you will receive an InvalidOperationException .

If you have previously hold down a key lets say key A, and then you try to hold down D key the new key code will be D instead of A even though two keys are held down at the same time. You can test out this behavior in notepad.

Since you are on WinForm you don't have the access to the Win32 Keyboard wrapper. You will need to do some manual tracking yourself.

You can have a HashSet<Keys> to store the keys currently being held down. You add the new keys in KeyDown event and Removes them in KeyUp event. Then you can iterate thru the list to check which keys are currently down and act accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM