简体   繁体   English

按键事件取消其他C#

[英]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. 我有2个后台工作人员(每个玩家一个),并且有按键事件将这些后台工作人员打开。 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. 好的,所以我必须键入它,因为它在另一台没有互联网的计算机上,但这是keydown事件中的代码。 The variables tells that in the background worker which if statement to do. 变量告诉在后台工作程序中执行哪个if语句。 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. 但是,主要问题是,每当我同时按下D键和向左箭头键时,就会停止在另一个单击之前的操作,并且会启动最近的键事件。 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. 首先,只要按下任意键,KeyDown事件就会每秒触发多次。

This means if RunWorkerAsync(); 这意味着如果RunWorkerAsync(); did not finish before the event fires for the second time you will receive an InvalidOperationException . 在事件第二次触发之前未完成,您将收到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. 如果您之前按住过一个键,请说出键A,然后尝试按住D键,即使同时按下两个键,新的键控代码也会是D而不是A。 You can test out this behavior in notepad. 您可以在记事本中测试此行为。

Since you are on WinForm you don't have the access to the Win32 Keyboard wrapper. 由于您使用的是WinForm,因此您无权访问Win32 Keyboard包装程序。 You will need to do some manual tracking yourself. 您将需要自己进行一些手动跟踪。

You can have a HashSet<Keys> to store the keys currently being held down. 您可以具有HashSet<Keys>来存储当前按住的键。 You add the new keys in KeyDown event and Removes them in KeyUp event. 您在KeyDown事件中添加新的键,并在KeyUp事件中删除它们。 Then you can iterate thru the list to check which keys are currently down and act accordingly. 然后,您可以遍历列表以检查当前哪些键处于按下状态并采取相应措施。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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